Get started
Рефакторинг стану з пріоритетом бази даних
Рефакторинг стану за принципом Database-First
Рішення
Використовувати дворівневу SQLite-схему:
- Глобальна база даних:
~/.openclaw/state/openclaw.sqlite - База даних агента: одна SQLite-база даних на агента для робочого простору, стенограми, VFS, артефактів і великого runtime-стану, що належить агенту
- Конфігурація залишається файловою:
openclaw.jsonлишається поза базою даних. Runtime-профілі автентифікації переходять у SQLite; файли облікових даних зовнішнього провайдера або CLI залишаються керованими власником поза базою даних OpenClaw.
Глобальна база даних є базою даних control-plane. Вона володіє виявленням агентів, спільним станом Gateway, спарюванням, станом пристроїв/вузлів, журналами завдань і потоків, станом Plugin, runtime-станом планувальника, метаданими резервних копій і станом міграцій.
База даних агента є базою даних data-plane. Вона володіє метаданими сесії агента, потоком подій стенограми, робочим простором VFS або scratch-простором імен, артефактами інструментів, артефактами запусків і доступними для пошуку/індексування локальними кеш-даними агента.
Це дає один довговічний глобальний вигляд без примусового перенесення великих робочих просторів агентів, стенограм і бінарних scratch-даних у спільну смугу запису Gateway.
Жорсткий контракт
Ця міграція має одну канонічну runtime-форму:
- Рядки сесій зберігають лише метадані сесії. Вони не повинні зберігати
transcriptLocator, файлові шляхи стенограм, sibling JSONL-шляхи, шляхи lock-файлів, метадані pruning або вказівники сумісності файлової епохи. - Ідентичність стенограми завжди є SQLite-ідентичністю:
{agentId, sessionId}плюс необов’язкові метадані теми там, де вони потрібні протоколу. sqlite-transcript://...не є runtime- або протокольною ідентичністю. Новий код не повинен виводити, зберігати, передавати, парсити або мігрувати локатори стенограм. Runtime і тести взагалі не повинні містити псевдолокаторів; документація може згадувати цей рядок лише щоб заборонити його.- Застарілі
sessions.json, transcript JSONL,.jsonl.lock, pruning, truncation і стара логіка session-path належать лише до шляху doctor-міграції/імпорту. - Застарілі псевдоніми конфігурації сесій належать лише до doctor-міграції. Runtime не
інтерпретує
session.idleMinutes,session.resetByType.dmабо cross-agentagent:main:*псевдоніми main-session для іншого налаштованого агента. - Ідентичність маршрутизації сесії є типізованим реляційним станом. Гарячі runtime- та UI-шляхи
мають читати
sessions.session_scope,sessions.account_id,sessions.primary_conversation_id,conversationsіsession_conversations; вони не повинні парситиsession_keyабо добуватиsession_entries.entry_jsonдля ідентичності провайдера, окрім як compatibility shadow, поки старі call sites видаляються. - Маркери прямих повідомлень рівня каналу, як-от
dmпротиdirect, є словником маршрутизації, а не локаторами стенограм або handles сумісності файлового сховища. - Застаріла конфігурація hook handler належить лише до поверхонь doctor-попередження/міграції.
Runtime не повинен завантажувати
hooks.internal.handlers; hooks виконуються лише через виявлені директорії hook і метаданіHOOK.md. - Runtime startup, гарячі шляхи відповіді, Compaction, reset, recovery, diagnostics,
TTS, memory hooks, subagents, маршрутизація команд Plugin, межі протоколу та
hooks повинні передавати
{agentId, sessionId}через runtime. - Тести мають seed-ити й перевіряти рядки SQLite-стенограм через
{agentId, sessionId}. Тести, які лише доводять forwarding JSONL-шляху, збереження caller-supplied locator або сумісність transcript-file, треба видалити, якщо вони не покривають doctor-імпорт, non-session support/debug materialization або форму протоколу. runEmbeddedPiAgent(...), підготовлені worker-запуски та внутрішня embedded-спроба не повинні приймати локатори стенограм. Вони відкривають SQLite transcript manager за{agentId, sessionId}і передають цей manager до internalized PI-compatible agent session, щоб застарілі callers не могли змусити runner записувати JSON/JSONL-стенограми.- Діагностика runner має зберігати runtime/cache/payload trace records у SQLite. Runtime-діагностика не повинна відкривати JSONL file override knobs або generic transcript JSONL export helpers; користувацькі експорти можуть матеріалізувати явні артефакти з рядків бази даних без передавання імен файлів назад у runtime.
- Raw stream logging використовує
OPENCLAW_RAW_STREAM=1плюс SQLite diagnostics rows. Старий pi-mono контракт файлового loggerPI_RAW_STREAM,PI_RAW_STREAM_PATHіraw-openai-completions.jsonlне є частиною runtime або тестів OpenClaw. - QMD memory indexing не повинен експортувати SQLite-стенограми у markdown-файли. QMD індексує лише налаштовані memory-файли; пошук стенограм сесій залишається SQLite-backed.
- QMD SDK subpath є QMD-only для нового коду. Помічники індексування SQLite session transcript
живуть у
memory-core-host-engine-session-transcripts; будь-який QMD re-export є лише сумісністю і не повинен використовуватися runtime-кодом. - Вбудовані memory indexes живуть у базі даних агента-власника. Runtime config і
resolved runtime contracts не повинні відкривати
memorySearch.store.path; doctor видаляє цей застарілий config key, а поточний код передає агентськийdatabasePathвнутрішньо.
Робота з реалізації має продовжувати видаляти код, доки ці твердження не стануть істинними без винятків поза межами doctor/import/export/debug.
Цільовий стан і прогрес
Жорстка ціль
- Одна глобальна SQLite-база даних володіє control-plane станом:
state/openclaw.sqlite. - Одна SQLite-база даних на агента володіє data-plane станом:
agents/<agentId>/agent/openclaw-agent.sqlite. - Конфігурація залишається файловою.
openclaw.jsonне є частиною цього рефакторингу бази даних. - Застарілі файли є лише вхідними даними doctor-міграції.
- Runtime ніколи не записує й не читає session або transcript JSONL як активний стан.
Цільові стани
not-started: runtime-код файлової епохи все ще записує активний стан.migrating: doctor/import код може перенести файлові дані в SQLite.dual-read: тимчасовий міст читає і SQLite, і застарілі файли. Цей стан заборонений для цього рефакторингу, якщо його явно не задокументовано як doctor-only.sqlite-runtime: runtime читає і записує лише SQLite.clean: застарілі runtime API й тести видалено, а guard запобігає регресіям.done: документація, тести, резервне копіювання, doctor-міграція і changed checks доводять clean-стан.
Поточний стан
- Сесії:
cleanдля runtime. Рядки сесій живуть у базі даних на агента, runtime API використовують{agentId, sessionId}або{agentId, sessionKey}, аsessions.jsonє лише doctor-only застарілим входом. - Стенограми:
cleanдля runtime. Події стенограм, ідентичності, snapshots і trajectory runtime events живуть у базі даних на агента. Runtime більше не приймає локатори стенограм або JSONL-шляхи стенограм. - PI embedded runner:
clean. Embedded PI runs, prepared workers, Compaction і retry loops використовують SQLite session scope і відхиляють застарілі transcript handles. - Cron:
cleanдля runtime. Runtime використовуєcron_jobsіcron_run_logs; runtime-тести використовують SQLitestoreKeynaming, а файлові cron-шляхи залишаються лише в doctor legacy migration tests. - Реєстр завдань:
clean. Runtime-рядки Task і Task Flow живуть уstate/openclaw.sqlite; unshipped sidecar SQLite importers видалено. - Стан Plugin:
clean. Рядки стану/blob Plugin живуть у спільній глобальній базі даних; старі plugin-state sidecar SQLite helpers захищені guard. - Пам’ять:
sqlite-runtimeдля вбудованої пам’яті та індексування стенограм сесій. Таблиці memory index живуть у базі даних на агента, memory state Plugin використовує спільні plugin-state rows, а застарілі memory-файли є вхідними даними doctor-міграції або вмістом користувацького робочого простору. - Резервне копіювання:
sqlite-runtime. Етапи резервного копіювання compact SQLite snapshots, пропускають live WAL/SHM sidecars, перевіряють SQLite integrity і записують backup runs у глобальну базу даних. - Doctor migration:
migrating, навмисно. Doctor імпортує застарілі JSON, JSONL і retired sidecar stores у SQLite, записує migration runs/sources і видаляє успішні джерела. - E2E scripts:
cleanдля runtime coverage. Docker MCP seeding записує SQLite rows. Runtime-context Docker script створює застарілий JSONL лише всередині doctor migration seed і явно називає legacy session index path.
Залишкова робота
- [x] Перейменувати змінні cron runtime-test store подалі від
storePath, якщо вони не є doctor legacy inputs. Файли:src/cron/service.test-harness.ts,src/cron/service.runs-one-shot-main-job-disables-it.test.ts,src/cron/service/timer.regression.test.ts,src/cron/service/ops.test.ts,src/cron/service/store.test.ts,src/cron/service.heartbeat-ok-summary-suppressed.test.ts,src/cron/service.main-job-passes-heartbeat-target-last.test.ts,src/cron/store.test.ts. Доказ:pnpm check:database-first-legacy-stores;rg -n 'storePath' src/cron --glob '!**/commands/doctor/**'. - [x] Видалити або перейменувати застарілі файлові export test mocks.
Файл:
src/auto-reply/reply/commands-export-test-mocks.ts. Доказ:rg -n 'resolveSessionFilePath|sessionFile|storePath|transcriptLocator' src/auto-reply/reply. - [x] Зробити Docker runtime-context legacy JSONL seed очевидно doctor-only.
Файл:
scripts/e2e/session-runtime-context-docker-client.ts. Доказ:rg -n 'sessions\\.json|sessionFile|\\.jsonl' scripts/e2e/session-runtime-context-docker-client.tsпоказує лишеseedBrokenLegacySessionForDoctorMigration. - [x] Підтримувати згенеровані Kysely типи узгодженими після будь-якої зміни схеми.
Файли:
src/state/openclaw-state-schema.sql,src/state/openclaw-agent-schema.sql,src/state/*generated*. Доказ: зміни схеми в цьому проході немає;pnpm db:kysely:check;pnpm lint:kysely. - [x] Повторно запустити focused tests для змінених stores, commands і scripts.
Доказ:
pnpm test src/cron/service/store.test.ts src/cron/store.test.ts src/cron/service.heartbeat-ok-summary-suppressed.test.ts src/cron/service.main-job-passes-heartbeat-target-last.test.ts src/cron/service.every-jobs-fire.test.ts src/cron/service.persists-delivered-status.test.ts src/cron/service.runs-one-shot-main-job-disables-it.test.ts src/cron/service/ops.test.ts src/cron/service/timer.regression.test.ts src/auto-reply/reply/commands-export-trajectory.test.ts extensions/telegram/src/thread-bindings.test.ts extensions/slack/src/monitor/message-handler/prepare.test.ts src/acp/translator.session-lineage-meta.test.ts;git diff --check. - [x] Перед оголошенням
doneзапустити changed gate або remote broad proof. Доказ:pnpm check:changed --timed -- <changed extension paths>пройшов на Hetzner Crabbox runrun_3f1cabf6b25cпісля тимчасового налаштування Node 24/pnpm і явної path routing для synced no-.gitworkspace.
Не регресувати
- Жодних transcript locators.
- Жодних активних session files.
- Жодних fake JSONL test fixtures, окрім doctor legacy migration tests.
- Жодного raw SQLite access там, де очікується Kysely.
- Жодних нових legacy DB migrations. Ця схема ще не постачалася; тримайте schema version
на
1, якщо немає вагомої причини.
Припущення після читання коду
Жодні подальші продуктові рішення не блокують цей план. Реалізація має продовжуватися з такими припущеннями:
- Використовуйте
node:sqliteнапряму та вимагайте середовище виконання Node 22+ для цього шляху сховища. - Залиште рівно один звичайний файл конфігурації. Не переносіть конфігурацію, маніфести Plugin або робочі області Git у SQLite під час цього рефакторингу.
- Файли сумісності середовища виконання не потрібні. Застарілі файли JSON і JSONL є лише вхідними даними міграції. Локальні для гілки sidecar-файли SQLite ніколи не постачалися й видаляються замість імпорту.
openclaw doctor --fixвідповідає за крок міграції застарілих файлів у базу даних. Запуск середовища виконання таopenclaw migrateне повинні містити застарілі шляхи оновлення бази даних OpenClaw.- Сумісність облікових даних дотримується того самого правила: облікові дані середовища виконання зберігаються в
SQLite. Старі файли
auth-profiles.json, поагентніauth.jsonі спільніcredentials/oauth.jsonє вхідними даними міграції doctor, а потім видаляються після імпорту. - Стан згенерованого каталогу моделей підтримується базою даних. Код середовища виконання не повинен записувати
agents/<agentId>/agent/models.json; наявні файлиmodels.jsonє застарілими вхідними даними doctor і видаляються після імпорту вagent_model_catalogs. - Середовище виконання не повинно мігрувати, нормалізувати або з’єднувати локатори транскриптів. Активна
ідентичність транскрипта — це
{agentId, sessionId}у SQLite. Шляхи файлів є лише застарілими вхідними даними doctor, аsqlite-transcript://...має зникнути з поверхонь середовища виконання, протоколу, хуків і Plugin, замість того щоб розглядатися як граничний дескриптор. - Читання транскриптів SQLite у середовищі виконання не запускають старі міграції форми записів JSONL і не переписують цілі транскрипти для сумісності. Нормалізація застарілих записів залишається в явних утилітах doctor/import. Doctor нормалізує застарілі файли транскриптів JSONL перед вставленням рядків SQLite; поточні рядки середовища виконання вже записані в поточній схемі транскриптів. Експорт траєкторії/сеансу читає ці рядки як є і не повинен виконувати застарілі міграції під час експорту.
- Допоміжні функції розбору/міграції застарілих транскриптів JSONL призначені лише для doctor. Код формату транскриптів середовища виконання будує лише поточний контекст транскриптів SQLite; doctor відповідає за оновлення старих записів JSONL перед вставленням рядків.
- Старий допоміжний модуль потокового передавання транскриптів JSONL, яким володіло середовище виконання, видалено. Код імпорту doctor відповідає за явне читання застарілих файлів; історія сеансів середовища виконання читає рядки SQLite.
- Прив’язки app-server Codex використовують OpenClaw
sessionIdяк канонічний ключ у просторі імен стану Plugin Codex.sessionKey— це метадані для маршрутизації/відображення й не повинен замінювати довговічний ідентифікатор сеансу або відроджувати ідентичність файла транскрипта. - Рушії контексту отримують поточний контракт середовища виконання напряму. Реєстр
не повинен обгортати рушії повторними shim-обгортками, які видаляють
sessionKey,transcriptScopeабоprompt; рушії, які не можуть приймати поточні параметри database-first, повинні явно падати, а не з’єднуватися мостом. - Вивід резервної копії має залишатися одним архівним файлом. Вміст бази даних має потрапляти до цього архіву як компактні знімки SQLite, а не як сирі live sidecar-файли WAL.
- Пошук транскриптів корисний, але не потрібний для першого database-first зрізу. Спроєктуйте схему так, щоб FTS можна було додати пізніше.
- Виконання worker має залишатися експериментальним за налаштуваннями, поки межа бази даних стабілізується.
Висновки читання коду
Поточна гілка вже пройшла етап proof-of-concept. Спільна
база даних існує, Node node:sqlite під’єднано через невеликий допоміжний модуль середовища виконання, а
колишні сховища тепер записують у state/openclaw.sqlite або у власну
базу даних openclaw-agent.sqlite.
Робота, що залишилася, полягає не у виборі SQLite; вона полягає в тому, щоб утримати нову межу чистою і видалити всі інтерфейси у формі сумісності, які все ще виглядають як старий файловий світ:
- Session
storePathбільше не є ідентичністю середовища виконання, формою тестової фікстури або полем корисного навантаження статусу. Тести середовища виконання та моста більше не містять назву контрактуstorePath; код doctor/міграції володіє цією застарілою лексикою. - Записи сеансів більше не проходять через стару внутрішньопроцесну чергу
store-writer.ts. Записи патчів SQLite натомість використовують виявлення конфліктів і обмежений повтор. - Виявлення застарілих шляхів усе ще має чинні застосування для міграції, але код середовища виконання має
припинити розглядати
sessions.jsonі файли транскриптів JSONL як можливі цілі запису. - Таблиці, якими володіє агент, живуть у поагентних базах даних SQLite. Глобальна БД зберігає
рядки реєстру/control-plane; ідентичність транскрипта — це
{agentId, sessionId}у поагентних рядках транскриптів. Код середовища виконання не повинен зберігати шляхи файлів транскриптів або мігрувати локатори транскриптів. - Doctor уже імпортує кілька застарілих файлів. Очищення полягає в тому, щоб зробити це єдиною явною реалізацією міграції, яку викликає doctor, зі стійким звітом про міграцію.
Жодні додаткові продуктові питання не блокують реалізацію.
Поточна форма коду
Гілка вже має справжню спільну базу SQLite:
- Мінімальна версія середовища виконання тепер Node 22+:
package.json, захист середовища виконання CLI, стандартні налаштування інсталятора, локатор середовища виконання macOS, CI та публічна документація зі встановлення узгоджені. Старий канал сумісності з Node 22 вилучено. src/state/openclaw-state-db.tsвідкриваєopenclaw.sqlite, задає WAL,synchronous=NORMAL,busy_timeout=30000,foreign_keys=ONі застосовує згенерований модуль схеми, похідний відsrc/state/openclaw-state-schema.sql.- Типи таблиць Kysely і модулі схеми середовища виконання генеруються з одноразових
баз даних SQLite, створених із зафіксованих файлів
.sql; код середовища виконання більше не зберігає скопійовані вручну рядки схем для глобальних, поагентних або проксі- баз даних захоплення. - Сховища середовища виконання виводять вибрані та вставлені типи рядків із цих згенерованих
інтерфейсів Kysely
DBзамість ручного дублювання форм рядків SQLite. Raw SQL залишається обмеженим застосуванням схеми, прагмами та DDL лише для міграцій. - Схеми SQLite зведено до
user_version = 1, бо ця структура бази даних ще не постачалася. Відкривачі середовища виконання створюють лише поточну схему; імпорт із файлу до бази даних лишається в коді doctor, а локальні для гілки допоміжні засоби оновлення бази даних видалено. - Реляційне володіння забезпечується там, де межа володіння є канонічною:
рядки міграції джерел каскадують від
migration_runs, стан доставки завдань каскадує відtask_runs, а рядки ідентичності транскриптів каскадують від подій транскриптів. - Поточні спільні таблиці включають
agent_databases,auth_profile_stores,auth_profile_state,plugin_state_entries,plugin_blob_entries,media_blobs,skill_uploads,capture_sessions,capture_events,capture_blobs,sandbox_registry_entries,cron_run_logs,cron_jobs,commitments,delivery_queue_entries,model_capability_cache,workspace_setup_state,native_hook_relay_bridges,current_conversation_bindings,plugin_binding_approvals,tui_last_sessions,acp_sessions,acp_replay_sessions,acp_replay_events,task_runs,task_delivery_state,flow_runs,subagent_runs,migration_runsіbackup_runs. - Довільний стан, яким володіє plugin, не отримує типізованих таблиць, якими володіє хост. Установлені
plugins використовують
plugin_state_entriesдля версіонованих JSON-навантажень іplugin_blob_entriesдля байтів, із володінням просторами імен/ключами, очищенням TTL, резервним копіюванням і записами міграцій plugin. Стан оркестрації plugins, яким володіє хост, усе ще може мати типізовані таблиці, коли хост володіє контрактом запитів, наприкладplugin_binding_approvals. - Міграції plugin — це міграції даних у просторах імен, якими володіє plugin, а не міграції
схеми хоста. Plugin може мігрувати власні версіоновані записи стану/blob
через провайдер міграцій, а хост записує стан джерела/запуску у
звичайний журнал міграцій. Нові встановлення plugin не потребують змін
openclaw-state-schema.sql, якщо сам хост не бере у володіння новий міжplugin-ний контракт. src/state/openclaw-agent-db.tsвідкриваєagents/<agentId>/agent/openclaw-agent.sqlite, реєструє базу даних у глобальній DB і володіє агент-локальними таблицями сеансів, транскриптів, VFS, артефактів, кешу та індексу памʼяті. Спільне виявлення середовища виконання тепер читає згенеровано-типізований реєстрagent_databasesзамість повторної реалізації цього запиту в кожному місці виклику.- Глобальні та поагентні бази даних записують рядок
schema_metaз роллю бази даних, версією схеми, часовими мітками та ідентифікатором агента для агентних баз даних. Структура все ще лишається наuser_version = 1, бо ця схема SQLite ще не постачалася. - Ідентичність поагентного сеансу тепер має канонічну кореневу таблицю
sessionsіз ключемsession_id, зsession_key,session_scope,account_id,primary_conversation_id, часовими мітками, полями відображення, метаданими моделі, ідентифікатором harness і звʼязками parent/spawn як колонками, доступними для запитів.session_routesє унікальним активним індексом маршруту відsession_keyдо поточногоsession_id, тож ключ маршруту може перейти до нового довговічного сеансу без потреби для гарячих читань вибирати між дубльованими рядкамиsessions.session_key. Старе суміснісно-сформоване навантаженняsession_entries.entry_jsonпривʼязане до довговічного кореняsession_idзовнішнім ключем; воно більше не є єдиним представленням сеансу на рівні схеми. - Ідентичність зовнішньої розмови для агента теж реляційна:
conversationsзберігає нормалізовану ідентичність провайдера/облікового запису/розмови, аsession_conversationsповʼязує один сеанс OpenClaw з однією або кількома зовнішніми розмовами. Це покриває DM-сеанси shared-main, де кілька учасників можуть навмисно зіставлятися з одним сеансом без неправди вsession_key. SQLite також забезпечує унікальність для природної ідентичності провайдера, тож той самий кортеж channel/account/kind/peer/thread не може розгалужуватися між ідентифікаторами розмов. Прямих учасників shared-main повʼязано з роллюparticipant, тож один сеанс OpenClaw може представляти кількох зовнішніх DM-учасників без пониження старіших учасників до нечітких related-рядків.sessions.primary_conversation_idусе ще вказує на поточну типізовану ціль доставки. Закриті колонки маршрутизації/стану забезпечуються обмеженнями SQLiteCHECK, а не лише TypeScript-union. Проєкція сеансу середовища виконання очищає суміснісні тіні маршрутизації зsession_entries.entry_jsonперед застосуванням типізованих колонок сеансу/розмови, тож застарілі JSON-навантаження не можуть воскресити цілі доставки. Маршрутизація оголошення subagent так само потребує типізованого контексту доставки SQLite; вона більше не повертається до суміснісних полів маршрутуSessionEntry. Явне успадкування доставки Gatewaychat.sendчитає типізований контекст доставки SQLite замість суміснісних полівorigin/last*.tools.effectiveтак само виводить контекст provider/account/thread із типізованих рядків доставки/маршрутизації SQLite, а не із застарілих тінейlast*запису сеансу. Контекст prompt для системних подій перебудовує поля channel/to/account/thread із типізованих полів доставки замість тінейorigin. Спільний helperdeliveryContextFromSessionі mapper сеансу до розмови тепер повністю ігноруютьSessionEntry.origin; лише типізовані поля доставки та реляційні рядки розмов можуть створювати гарячу ідентичність маршруту. Нормалізація запису сеансу середовища виконання вилучаєoriginперед збереженням або проєктуваннямentry_json, а вхідні метадані записують типізовані поля channel/chat плюс реляційні рядки розмов замість створення нових тіней origin. - Події транскриптів, знімки транскриптів і runtime-події траєкторії тепер
посилаються на канонічний поагентний корінь
sessionsі каскадують під час видалення сеансу. Рядки ідентичності/ідемпотентності транскриптів далі каскадують від точного рядка події транскрипту. - Індекси memory-core тепер використовують явні таблиці агентної бази даних
memory_index_meta,memory_index_sources,memory_index_chunksіmemory_embedding_cache, аmemory_index_stateвідстежує зміни ревізій. Необовʼязкові бічні FTS/vector-індекси названіmemory_index_chunks_ftsіmemory_index_chunks_vecзамість загальних таблицьmeta,files,chunks,chunks_ftsабоchunks_vec. Канонічні назви зберігають поточну форму рядка path/source і сумісність серіалізованих embedding. Ці таблиці є похідним/пошуковим кешем, а не канонічним сховищем транскриптів; їх можна видалити й перебудувати з файлів робочої області памʼяті та налаштованих джерел. Відкриття поставленого індексу памʼяті із загальними назвами мігрує його метадані, джерела, chunks і кеш embedding у канонічні таблиці; похідні FTS/vector таблиці перебудовуються під їхніми канонічними назвами. - Стан відновлення запусків subagent тепер живе в типізованих спільних рядках
subagent_runsз індексованими ключами дочірнього, requester і controller сеансів. Старий файлsubagents/runs.jsonє лише вхідними даними міграції doctor. - Поточні привʼязки розмов тепер живуть у типізованих спільних
рядках
current_conversation_bindingsіз ключем за нормалізованим ідентифікатором розмови, з колонками цільового агента/сеансу, видом розмови, статусом, строком дії та метаданими, збереженими як реляційні колонки замість дубльованого непрозорого запису привʼязки. Довговічний ключ привʼязки включає нормалізований вид розмови, тож refs прямих/group/channel не можуть конфліктувати, а SQLite відхиляє неприпустимі значення виду/статусу привʼязки. Старий файлbindings/current-conversations.jsonє лише вхідними даними міграції doctor. - Відновлення черги доставки тепер накладає типізовані колонки черги для channel, target,
account, session, retry, error, platform-send і стану відновлення на
replay JSON.
entry_jsonзберігає replay-навантаження, hooks і форматувальне навантаження, але типізовані колонки є авторитетними для гарячої маршрутизації/стану черги. - Вказівники відновлення останнього сеансу TUI тепер живуть у типізованих спільних
рядках
tui_last_sessionsіз ключем за хешованою областю підключення/сеансу TUI. Старий JSON-файл TUI є лише вхідними даними міграції doctor. - Стандартні налаштування TTS тепер живуть у спільних SQLite-рядках стану plugin з ключем під
plugin
speech-core. Старий файлsettings/tts.jsonє лише вхідними даними міграції doctor; середовище виконання більше не читає й не записує JSON-файли налаштувань TTS, а legacy-розвʼязувач шляху живе в модулі міграції doctor. - Метадані цілі secret тепер говорять про сховища, а не вдають, що кожна
ціль облікових даних є файлом конфігурації.
openclaw.jsonлишається сховищем конфігурації; цілі auth-profile використовують типізовані SQLite-рядкиauth_profile_storesз обліковими даними у формі провайдера, збереженими як JSON-навантаження. - Аудит secret більше не сканує вилучені поагентні файли
auth.json. Doctor володіє попередженням про цей legacy-файл, його імпортом і видаленням. - Legacy-допоміжні засоби шляхів профілів auth тепер живуть у legacy-коді doctor. Допоміжні засоби шляхів
core auth profile показують ідентичність SQLite auth-store та місця відображення,
а не runtime-шляхи
auth-profiles.jsonчиauth-state.json. - Модулі середовища виконання відновлення запусків subagent і кешу можливостей моделей OpenRouter
тепер тримають читачі/писачі знімків SQLite окремо від допоміжних засобів імпорту legacy JSON,
що призначені лише для doctor. Можливості OpenRouter використовують типізовані загальні
рядки
model_capability_cacheпідprovider_id = "openrouter"замість одного непрозорого cache blob або специфічної для провайдера таблиці хоста.taskNameзапуску subagent зберігається в типізованій колонціsubagent_runs.task_name; копіяpayload_jsonє даними для replay/debug, а не джерелом для гарячих полів відображення або lookup. src/agents/filesystem/virtual-agent-fs.sqlite.tsреалізує SQLite VFS поверх таблиціvfs_entriesагентної бази даних. Читання директорій, рекурсивні експорти, видалення та перейменування використовують індексовані діапазони префіксів(namespace, path)замість сканування всього простору імен або покладання на зіставлення шляхів черезLIKE.src/agents/runtime-worker.entry.tsстворює по-запускові SQLite VFS, артефакти tool, артефакти запуску та scoped cache stores для workers.- Маркери завершення bootstrap робочої області тепер живуть у типізованих спільних
рядках
workspace_setup_stateіз ключем за розвʼязаним шляхом робочої області замість.openclaw/workspace-state.json; середовище виконання більше не читає й не перезаписує legacy-маркер робочої області, а helper API більше не передають фальшивий шлях.openclaw/setup-stateлише для виведення ідентичності сховища. - Схвалення exec тепер живуть у типізованому singleton-рядку спільної SQLite
exec_approvals_config. Doctor імпортує legacy~/.openclaw/exec-approvals.json; записи середовища виконання більше не створюють, не перезаписують і не повідомляють цей файл як його активне місце сховища. Супутній застосунок macOS читає й записує той самий рядок таблиціstate/openclaw.sqlite; він зберігає на диску лише Unix prompt socket, бо це IPC, а не довговічний стан середовища виконання. - Модулі середовища виконання ідентичності пристрою, auth пристрою та bootstrap тепер тримають свої
читачі/писачі знімків SQLite окремо від допоміжних засобів імпорту legacy JSON, призначених лише для doctor.
Ідентичність пристрою використовує типізовані рядки
device_identities, а токени auth пристрою використовують типізовані рядкиdevice_auth_tokens. Записи auth пристрою узгоджують рядки за device/role замість обрізання таблиці токенів, а середовище виконання більше не маршрутизує оновлення одного токена через старий whole-store adapter. Legacy JSON-навантаження версії 1 існують лише як форми імпорту/експорту doctor. - Кеш обміну токенів GitHub Copilot використовує спільну таблицю стану Plugin у SQLite
за
github-copilot/token-cache/default. Це кешований стан, яким володіє провайдер, тому він навмисно не додає таблицю схеми хоста. - Compaction GitHub Copilot більше не записує побічні файли робочого простору
openclaw-compaction-*.json. Harness викликає RPC Compaction історії SDK для відстежуваного сеансу SDK, а OpenClaw зберігає довговічний стан сеансу/транскрипту в SQLite замість файлів-маркерів сумісності. - Спільний runtime Swift (
OpenClawKit) використовує ті самі рядкиstate/openclaw.sqliteдля ідентичності пристрою та автентифікації пристрою. Помічники застосунку macOS імпортують спільні помічники SQLite замість володіння другим JSON- або SQLite-шляхом. Залишковий застарілийidentity/device.jsonблокує створення ідентичності, доки doctor не імпортує його в SQLite, що відповідає стартовому шлюзу TypeScript і Android. - Ідентичність пристрою Android використовує той самий сумісний із TypeScript ключовий матеріал,
збережений у типізованих рядках
state/openclaw.sqlite#table/device_identities. Він ніколи не читає і не записуєopenclaw/identity/device.json; залишковий застарілий файл блокує запуск, доки doctor не імпортує його в SQLite. - Кешовані токени автентифікації пристрою Android також використовують типізовані
рядки
state/openclaw.sqlite#table/device_auth_tokensі мають ту саму семантику токенів версії 1, що й TypeScript та Swift. Runtime більше не читає ключі сумісностіSecurePrefsgateway.deviceToken*; вони належать лише логіці міграції/doctor. - Історія нещодавніх пакетів сповіщень Android використовує типізовані
рядки
android_notification_recent_packages. Runtime більше не мігрує і не читає старі CSV-ключі SharedPreferences. - Створення ідентичності пристрою завершується закритою відмовою, коли існує застарілий
identity/device.json, коли рядок ідентичності SQLite недійсний або коли сховище ідентичності SQLite неможливо відкрити. Doctor спершу імпортує та видаляє цей файл, тому запуск runtime не може непомітно змінити ідентичність сполучення до міграції. - Вибір ідентичності пристрою є ключем рядка SQLite, а не локатором JSON-файлу. Тести
й помічники Gateway передають явні ключі ідентичності; лише міграція doctor і
стартовий шлюз із закритою відмовою знають назву вилученого файлу
identity/device.json. - Сумісність скидання сеансу тепер живе в міграції конфігурації doctor:
session.idleMinutesпереноситься вsession.reset.idleMinutes,session.resetByType.dmпереноситься вsession.resetByType.direct, а runtime-політика скидання читає лише канонічні ключі скидання. - Сумісність застарілої конфігурації тепер живе під
src/commands/doctor/. Звичайна валідаціяreadConfigFileSnapshot()не імпортує застарілі детектори doctor і не анотує застарілі проблеми;runDoctorConfigPreflight()додає ці проблеми для ремонту/звітування doctor. Потік конфігурації doctor імпортуєsrc/commands/doctor/legacy-config.ts, а старий ремонт ідентифікаторів OAuth-профілів живе підsrc/commands/doctor/legacy/oauth-profile-ids.ts. - Команди не-doctor не запускають автоматично ремонт застарілої конфігурації. Наприклад,
openclaw update --channelтепер завершується помилкою на недійсній застарілій конфігурації та просить користувача запустити doctor, замість непомітного імпорту коду міграції doctor. - Web push, APNs, Voice Wake, перевірки оновлень і стан конфігурації тепер використовують типізовані спільні таблиці SQLite для підписок, VAPID-ключів, реєстрацій вузлів, рядків тригерів, рядків маршрутизації, стану сповіщень про оновлення та записів стану конфігурації замість цілих непрозорих JSON-блобів. Записи знімків Web push і APNs тепер узгоджують підписки/реєстрації за первинним ключем замість очищення їхніх таблиць; стан конфігурації робить те саме за шляхом конфігурації. Їхні runtime-модулі тримають читачі/записувачі знімків SQLite окремо від допоміжних імпортерів застарілого JSON, призначених лише для doctor.
- Конфігурація Node-хоста тепер використовує типізований singleton-рядок у спільній базі даних SQLite;
doctor імпортує старий файл
node.jsonперед звичайним використанням runtime. - Сполучення пристрою/вузла, сполучення каналів, allowlist каналів і стан bootstrap
тепер використовують типізовані рядки SQLite замість цілих непрозорих JSON-блобів. Схвалення прив’язок Plugin
і стан завдань Cron дотримуються того самого поділу: runtime-модулі надають
операції на основі SQLite та нейтральні помічники знімків, а записи знімків сполучення/bootstrap
і схвалення прив’язок Plugin узгоджують рядки за первинним ключем
замість обрізання таблиць, тоді як doctor імпортує/видаляє старі JSON-файли через
модулі
src/commands/doctor/legacy/*. - Записи встановлених Plugin тепер живуть в індексі встановлених Plugin у SQLite.
Runtime-читання/запис конфігурації більше не мігрує і не зберігає старі
дані авторської конфігурації
plugins.installs; doctor імпортує цю застарілу форму конфігурації в SQLite перед звичайним використанням runtime. - Знімки відновлення облікових даних QQBot тепер живуть у стані Plugin SQLite під
qqbot/credential-backups. Runtime більше не записуєqqbot/data/credential-backup*.json; контракт doctor QQBot імпортує та архівує ці застарілі файли резервних копій з активного каталогу стану. - Планування перезавантаження Gateway порівнює знімки індексу встановлених Plugin SQLite під
внутрішнім простором імен diff
installedPluginIndex.installRecords.*. Рішення runtime щодо перезавантаження більше не обгортають ці рядки у фальшиві об’єкти конфігураціїplugins.installs. - Оновлення облікових даних іменованого акаунта Matrix більше не відбувається під час runtime
читань. Doctor володіє перейменуванням старого верхньорівневого
credentials/matrix/credentials.json, коли можна визначити один/default акаунт Matrix. - Основні модулі runtime для сполучення та cron більше не експортують застарілі побудовники JSON-шляхів.
Застарілі модулі, якими володіє doctor, створюють вихідні шляхи
pending.json,paired.json,bootstrap.jsonіcron/jobs.jsonлише для тестів імпорту та міграції. Нормалізація застарілої форми завдань cron і імпорт журналу запусків cron живуть підsrc/commands/doctor/legacy/cron*.ts. src/commands/doctor/legacy/runtime-state.tsімпортує застарілі JSON-файли стану, включно з конфігурацією хоста вузла, у SQLite з doctor. Нові імпортери застарілих файлів залишаються підsrc/commands/doctor/legacy/.src/commands/doctor/state-migrations.tsімпортує застаріліsessions.jsonі транскрипти*.jsonlбезпосередньо в SQLite та видаляє успішні джерела. Він більше не проміжно розміщує кореневі застарілі транскрипти черезagents/<agentId>/sessions/*.jsonlі не створює канонічну ціль JSONL перед імпортом.- Перевірки цілісності стану doctor більше не сканують застарілі каталоги сеансів і не пропонують видалення осиротілих JSONL. Застарілі файли транскриптів є лише вхідними даними міграції, а крок міграції володіє імпортом і видаленням джерел.
- Імпорт застарілого реєстру sandbox живе під
src/commands/doctor/legacy/sandbox-registry.ts; активні читання і записи реєстру sandbox залишаються лише SQLite. - Застарілий ремонт стану/імпорту транскриптів сеансів живе під
src/commands/doctor/legacy/session-transcript-health.ts; runtime-модулі команд більше не містять парсинг JSONL-транскриптів або код ремонту активної гілки.
Основні моменти завершеної консолідації/видалення:
- Стан Plugin тепер використовує спільну базу даних
state/openclaw.sqlite. Старий імпортер sidecarplugin-state/state.sqlite, локальний для гілки, видалено, тому що ця SQLite-схема ніколи не постачалася. Допоміжні засоби probe/test повідомляють спільнийdatabasePathзамість розкриття специфічного для стану Plugin шляху SQLite. - Таблиці середовища виконання завдань і TaskFlow тепер зберігаються у спільній
базі даних
state/openclaw.sqliteзамістьtasks/runs.sqliteіtasks/flows/registry.sqlite; старі sidecar-імпортери видалено з тієї самої причини непоставленої схеми. src/config/sessions/store.tsбільше не потребуєstorePathдля вхідних метаданих, оновлень маршруту або читання updated-at. Збереження команд, очищення сесій CLI, глибина підагентів, перевизначення автентифікації та ідентичність сесії транскрипта використовують API рядків агента/сесії. Записи застосовуються як патчі рядків SQLite з оптимістичним повтором у разі конфлікту.- Розв’язання цілі сесії тепер розкриває цілі бази даних для кожного агента, а не
застарілі шляхи
sessions.json. Спільний Gateway, метадані ACP, виправлення маршрутів doctor іopenclaw sessionsперелічуютьagent_databasesплюс налаштованих агентів. - Маршрутизація сесій Gateway тепер використовує
resolveGatewaySessionDatabaseTarget; повернена ціль міститьdatabasePathі кандидатні ключі рядків SQLite замість застарілого файлового шляху сховища сесій. - Типи середовища виконання сесій каналів тепер розкривають
{agentId, sessionKey}для читання updated-at, вхідних метаданих і оновлень останнього маршруту. Старий суміснісний типsaveSessionStore(storePath, store)вилучено. - Середовище виконання Plugin, API розширень і barrel-поверхні
config/sessionsтепер спрямовують код Plugin до допоміжних засобів рядків сесій на базі SQLite. Суміснісні експорти кореневої бібліотеки (loadSessionStore,saveSessionStore,resolveStorePath) залишаються як застарілі шими для наявних споживачів. Старий допоміжний засібresolveLegacySessionStorePathвилучено; побудова застарілого шляхуsessions.jsonтепер локальна для міграції та тестових фікстур. src/config/sessions/session-entries.sqlite.tsтепер зберігає канонічні записи сесій у базі даних кожного агента та підтримує читання/upsert/delete-патчі на рівні рядків. Runtime upsert/patch/delete більше не сканує варіанти регістру й не очищає застарілі ключі-псевдоніми; канонізація належить doctor. Окремий допоміжний засіб імпорту JSON вилучено, а міграція зливає upsert-ом новіші рядки замість заміни всієї таблиці сесій. Публічні допоміжні засоби read/list/load проєктують гарячі метадані сесій із типізованих рядківsessionsіconversations;entry_jsonє суміснісною/налагоджувальною тінню й може бути застарілим або недійсним без втрати типізованої ідентичності сесії чи контексту доставки.src/config/sessions/delivery-info.tsтепер розв’язує контекст доставки з типізованих рядківsessions+conversations+session_conversationsу базі кожного агента. Він більше не реконструює ідентичність доставки runtime ізsession_entries.entry_json; відсутній типізований рядок розмови є проблемою міграції/виправлення doctor, а не runtime fallback.- Рішення щодо скидання збережених сесій тепер надають перевагу типізованим метаданим
sessions.session_scope,sessions.chat_typeіsessions.channel. РозбірsessionKeyзалишається лише для явних суфіксів thread/topic у цілях команд; класифікація скидання group vs direct більше не походить із форми ключа. - Класифікація відображення списку/статусу сесій тепер використовує типізовані метадані
чату та вид сесії Gateway. Вона більше не трактує підрядки
:group:або:channel:всерединіsession_keyяк довговічну істину group/direct. - Вибір політики silent-reply тепер використовує лише явний тип розмови або метадані
поверхні. Він більше не вгадує політику direct/group за підрядками
session_key. - Розв’язання моделі відображення сесії тепер отримує id агента з цілі бази даних сесії
SQLite замість виділення його з
session_key. - Гідратація цілі оголошення agent-to-agent тепер використовує лише типізований
deliveryContextізsessions.list. Вона більше не відновлює маршрутизацію channel/account/thread із застарілогоorigin, дзеркальних полівlast*або формиsession_key. - Відхилення thread-цілей
sessions_sendтепер читає типізовані метадані маршрутизації SQLite. Воно більше не відхиляє і не приймає цілі шляхом розбору суфіксів thread із ключа цілі. - Валідація групової політики інструментів тепер читає типізовану маршрутизацію розмов
SQLite для поточної або породженої сесії. Вона більше не довіряє ідентичності
group/channel через декодування
sessionKey; надані викликачем group ids відкидаються, коли жоден типізований рядок сесії їх не підтверджує. - Зіставлення перевизначень моделі каналу тепер використовує явні метадані групи та
батьківської розмови. Воно більше не декодує ідентифікатори батьківських розмов із
parentSessionKey. - Успадкування збережених перевизначень моделі тепер потребує явного ключа батьківської
сесії з типізованого контексту сесії. Воно більше не виводить батьківські перевизначення
із суфіксів
:thread:або:topic:уsessionKey. - Стару обгортку thread-info сесій і парсер thread завантаженого Plugin вилучено; жоден
runtime-код не імпортує
config/sessions/thread-info. - Допоміжний засіб розмов каналу більше не розкриває мости розбору повного ключа сесії.
Core і далі нормалізує сирі ідентифікатори розмов, що належать провайдеру, через
resolveSessionConversation(...), але не реконструює факти маршруту зsessionKey. - Доставка завершень, політика надсилання та обслуговування завдань більше не виводять
тип чату з форми
session_key. Старий парсер ключа типу чату видалено; ці шляхи потребують типізованих метаданих сесії, типізованого контексту доставки або явного словника цілі доставки. - Список/статус сесій, діагностика, прив’язування облікового запису схвалення, фільтрація
Heartbeat у TUI та підсумки використання більше не добувають із
SessionEntry.originмаршрутизацію provider/account/thread/display. Єдині runtime-читанняorigin, що залишилися, є несесійними поняттями або об’єктами доставки поточного ходу. - Нативний пошук розмови approval-request тепер читає типізовані рядки маршрутизації
сесій для кожного агента. Він більше не розбирає ідентичність channel/group/thread
розмови з
sessionKey; відсутні типізовані метадані є проблемою міграції/виправлення. - Payload-и подій Gateway session changed/chat/session більше не відлунюють
SessionEntry.originабо тіні маршрутуlast*; клієнти отримують типізованіchannel,chatTypeіdeliveryContext. - Розв’язання доставки Heartbeat тепер може отримувати типізований SQLite
deliveryContextнапряму, а runtime Heartbeat передає рядок доставки сесії кожного агента замість покладання на суміснісні тініsession_entriesдля поточної маршрутизації. - Розв’язання цілі доставки ізольованого агента Cron також гідратує свій поточний маршрут із типізованого рядка доставки сесії кожного агента перед fallback до суміснісного payload запису.
- Розв’язання походження оголошення підагентів тепер протягує типізований контекст доставки
requester-session через
loadRequesterSessionEntryі надає перевагу цьому рядку над суміснісними тінямиlast*/deliveryContext. - Оновлення вхідних метаданих сесії тепер спершу зливаються з типізованим рядком доставки
кожного агента; старі поля доставки
SessionEntryє лише fallback, коли типізованого рядка розмови не існує. - Витяг доставки restart/update тепер дозволяє типізованому SQLite delivery
threadIdмати пріоритет над фрагментами topic/thread, розібраними зsessionKey; розбір є лише fallback для застарілих ключів у формі thread. - Id каналів контексту hook-агента тепер надають перевагу типізованій ідентичності розмови
SQLite, потім явним метаданим повідомлення. Вони більше не розбирають фрагменти
provider/group/channel із
sessionKey. - Успадкування зовнішнього маршруту Gateway
chat.sendтепер читає типізовані метадані маршрутизації сесій SQLite замість виведення scope channel/direct/group із частинsessionKey. Сесії зі scope каналу успадковують лише тоді, коли типізований канал сесії та тип чату збігаються зі збереженим контекстом доставки; shared-main сесії зберігають своє суворіше правило CLI/без-клієнтських-метаданих. - Пробудження restart-sentinel і маршрутизація продовжень тепер читають типізовані рядки доставки/маршрутизації SQLite перед постановкою в чергу пробуджень Heartbeat або маршрутизованих продовжень agent-turn. Вони більше не реконструюють контекст доставки з JSON-тіні session-entry.
- Розв’язання контексту Gateway
tools.effectiveтепер читає типізовані рядки доставки/маршрутизації SQLite для входів provider, account, target, thread і reply-mode. Воно більше не відновлює ці гарячі поля маршрутизації із застарілих тіней origin уsession_entries.entry_json. - Маршрутизація realtime voice consult тепер розв’язує доставку parent/call із типізованих
рядків сесій SQLite для кожного агента. Вона більше не повертається до суміснісних тіней
SessionEntry.deliveryContextпід час вибору маршруту повідомлення вбудованого агента. - Ретрансляція Heartbeat для ACP spawn і маршрутизація parent-stream тепер читають доставку parent із типізованих рядків сесій SQLite. Вони більше не реконструюють контекст доставки parent із суміснісних тіней session-entry.
- Збереження маршруту доставки сесії тепер слідує типізованим метаданим чату та збереженим
стовпцям доставки. Воно більше не витягує підказки каналу, маркери direct/main або форму
thread із
sessionKey; внутрішні маршрути webchat успадковують зовнішню ціль лише тоді, коли SQLite вже має типізовану/збережену ідентичність доставки для сесії. - Загальний витяг доставки сесії тепер читає лише точний типізований рядок доставки сесії SQLite. Він більше не розбирає суфікси thread/topic і не виконує fallback із ключа у формі thread до базового ключа сесії.
- Диспетчеризація відповіді, відновлення restart sentinel і маршрутизація realtime voice consult тепер використовують точні типізовані рядки сесій/розмов SQLite для маршрутизації thread. Вони більше не відновлюють thread ids або контекст доставки базової сесії через розбір ключів сесій у формі thread.
- Обмеження історії Embedded PI тепер використовує типізовану проєкцію маршрутизації сесій
SQLite (
sessions+ primaryconversations) для provider, типу чату та ідентичності peer. Воно більше не розбирає provider, DM, group або форму thread ізsessionKey. - Виведення доставки інструментів Cron тепер використовує лише явну доставку або поточний
типізований контекст доставки. Воно більше не декодує цілі channel, peer, account або
thread із
agentSessionKey. - Runtime-рядки сесій більше не містять старий псевдонім маршруту
lastProvider. Допоміжні засоби й тести використовують типізовані поляlastChannelіdeliveryContext; міграція doctor є єдиним місцем, яке має перекладати старіші псевдоніми маршрутів або збережені тініorigin. - Події транскрипта, рядки VFS і рядки артефактів інструментів тепер записуються до бази даних кожного агента. Непоставлену глобальну таблицю зіставлення transcript-file вилучено; doctor натомість записує застарілі вихідні шляхи в довговічні рядки міграції.
- Runtime-пошук транскрипта більше не сканує байтові зміщення JSONL і не перевіряє застарілі файли транскриптів. Шляхи Gateway chat/media/history читають рядки транскрипта з SQLite; JSONL сесії тепер є лише застарілим входом doctor, а не runtime-станом чи форматом експорту.
- Батьківські та гілкові зв’язки транскрипта використовують структуровані метадані
parentTranscriptScope: {agentId, sessionId}у заголовках транскриптів SQLite, а не path-like locator-рядкиagent-db:...transcript_events.... - Контракт менеджера транскриптів більше не розкриває неявні збережені конструктори
create(cwd)абоcontinueRecent(cwd). Збережені менеджери транскриптів відкриваються з явним scope{agentId, sessionId}; лише in-memory менеджери залишаються без scope для тестів і чистих перетворень транскриптів. - API runtime-сховища транскриптів розв’язують scope SQLite, а не файлові шляхи. Старий
допоміжний засіб
resolve...ForPathі невикористані параметри записуtranscriptPathвилучено з runtime-викликачів. - Runtime-розв’язання сесій тепер використовує
{agentId, sessionId}і не повинно виводити рядкиsqlite-transcript://<agent>/<session>для зовнішніх меж. Застарілі абсолютні шляхи JSONL є лише входами міграції doctor. - Записи прямого bridge для нативного hook relay тепер зберігаються в типізованих спільних
рядках
native_hook_relay_bridges, ключованих за relay id. Runtime більше не записує JSON-реєстр у/tmpабо непрозорі generic records для цих короткоживучих bridge-записів. runEmbeddedPiAgent(...)більше не має параметра transcript-locator. Підготовлені дескриптори worker також не містять локаторів транскриптів. Стан сеансу середовища виконання та поставлені в чергу наступні запуски переносять{agentId, sessionId}замість похідних дескрипторів транскриптів.- Вбудоване Compaction тепер бере область SQLite з
agentIdіsessionId. Хуки Compaction, виклики context-engine, делегування CLI та відповіді протоколу не повинні отримувати похідні дескрипториsqlite-transcript://.... Код експорту/налагодження може матеріалізувати явні користувацькі артефакти з рядків, але не надає універсального шляху експорту JSONL сеансу й не передає імена файлів назад в ідентичність середовища виконання. /export-sessionчитає рядки транскрипта з SQLite і записує лише запитаний автономний HTML-перегляд. Вбудований переглядач більше не реконструює й не завантажує JSONL сеансу з цих рядків.- Делегування context-engine більше не розбирає локатор транскрипта, щоб відновити
ідентичність агента. Підготовлений контекст середовища виконання переносить розв’язаний
agentIdу вбудований адаптер Compaction. - Перезапис транскрипта й обрізання результатів live-інструментів тепер читають і зберігають
стан транскрипта за
{agentId, sessionId}і не виводять тимчасові локатори для корисних навантажень подій оновлення транскрипта. - Поверхня допоміжних засобів стану транскрипта більше не має варіантів
readTranscriptState,replaceTranscriptStateEventsабоpersistTranscriptStateMutationна основі локаторів. Виклики середовища виконання мають використовувати API{agentId, sessionId}. Імпорт Doctor читає застарілі файли за явним шляхом до файлу й записує рядки SQLite; він не мігрує рядки локаторів. - Контракт session-manager середовища виконання більше не надає
open(locator),forkFrom(locator)абоsetTranscriptLocator(...). Збережені менеджери сеансів відкриваються лише за{agentId, sessionId}; допоміжні засоби списку/форку живуть у рядково-орієнтованих API сеансів і контрольних точок замість фасаду менеджера транскриптів. - API читача транскриптів Gateway спершу працюють з областю. Вони приймають
{agentId, sessionId}і не приймають позиційний локатор транскрипта, який міг би випадково стати ідентичністю середовища виконання. Розбір локатора активного транскрипта прибрано; застарілі вихідні шляхи читає лише код імпорту Doctor. - Події оновлення транскрипта також спершу працюють з областю.
emitSessionTranscriptUpdateбільше не приймає голий рядок локатора, а слухачі маршрутизують за{agentId, sessionId}без розбору дескриптора. - Трансляція session-message Gateway розв’язує ключі сеансу з області агента/сеансу, а не з локатора транскрипта. Старий резолвер/кеш ключів transcript-locator-to-session прибрано.
- SSE історії сеансів Gateway фільтрує live-оновлення за областю агента/сеансу. Він більше не канонізує кандидатів локатора транскрипта, realpath або файлові ідентичності транскриптів, щоб вирішити, чи має потік отримати оновлення.
- Хуки життєвого циклу сеансу більше не виводять і не надають локатори транскриптів на
session_end. Споживачі хуків отримуютьsessionId,sessionKey, ідентифікатори наступного сеансу та контекст агента; файли транскриптів не є частиною контракту життєвого циклу. - Хуки скидання також більше не виводять і не надають локатори транскриптів. Корисне навантаження
before_resetпереносить відновлені повідомлення SQLite та причину скидання, тоді як ідентичність сеансу залишається в контексті хука. - Скидання harness агента більше не приймає локатор транскрипта. Надсилання скидання
обмежується
sessionId/sessionKeyплюс причиною. - Типи сеансів розширення агента більше не надають
transcriptLocator; розширення мають використовувати контекст сеансу та API середовища виконання, а не звертатися до файлової ідентичності транскрипта. - Хуки Compaction для Plugin більше не надають локатори транскриптів. Контекст хука вже переносить ідентичність сеансу, а читання транскриптів має проходити через API SQLite, що враховують область, замість файлових дескрипторів.
- Хуки
before_agent_finalizeбільше не надаютьtranscriptPath, включно з корисними навантаженнями ретрансляції native-хуків. Хуки фіналізації використовують лише контекст сеансу. - Відповіді скидання Gateway більше не синтезують локатор транскрипта в поверненому записі. Скидання створює рядки транскрипта SQLite, повертає чистий запис сеансу й залишає доступ до транскриптів читачам, що враховують область.
- Результати вбудованого запуску та Compaction більше не показують локатори транскриптів для
обліку сеансів. Автоматичне Compaction оновлює лише активний
sessionId, лічильники Compaction і метадані токенів. - Результати вбудованих спроб більше не повертають
transcriptLocatorUsed, а результати context-enginecompact()більше не повертають локатори транскриптів. Цикли повторних спроб середовища виконання приймають лише наступнийsessionId. - Результати додавання транскрипта delivery-mirror більше не повертають локатори
транскриптів. Виклики отримують доданий
messageId; сигнали оновлення транскрипта використовують область SQLite. - Допоміжні засоби форку батьківського сеансу повертають лише форкнутий
sessionId. Підготовка субагента передає область дочірнього агента/сеансу в рушії. - Параметри CLI runner і повторне засівання історії більше не приймають локатори транскриптів.
Читання історії CLI розв’язує область транскрипта SQLite з
{agentId, sessionId}і контексту ключа сеансу. - Фікстури тестів CLI та embedded-runner тепер засівають і читають рядки транскриптів SQLite
за ідентифікатором сеансу замість того, щоб удавати, що активні сеанси є файлами
*.jsonl, або передавати рядокsqlite-transcript://...через параметри середовища виконання. - Події guard для результатів інструментів сеансу надсилаються з відомої області сеансу, навіть коли
менеджер у пам’яті не має похідного локатора. Його тести більше не підробляють активні
файли транскриптів
/tmp/*.jsonl. - Допоміжні засоби BTW і compaction-checkpoint тепер читають і форкають рядки транскриптів за областю SQLite. Метадані контрольної точки тепер зберігають лише ідентифікатори сеансів та ідентифікатори leaf/entry; похідні локатори більше не записуються в корисні навантаження контрольних точок.
- Пошук transcript-key у Gateway використовує область транскрипта SQLite на межах протоколу і більше не виконує realpath або stat для імен файлів транскриптів.
- Автоматичне обертання транскриптів Compaction записує наступні рядки транскрипта безпосередньо через сховище транскриптів SQLite. Рядки сеансу зберігають лише ідентичність наступного сеансу, а не довговічний шлях JSONL чи збережений локатор.
- Вбудоване Compaction context-engine використовує допоміжні засоби обертання транскриптів з іменами SQLite. Тести обертання більше не створюють наступні шляхи JSONL і не моделюють активні сеанси як файли.
- Кероване збереження вихідних зображень формує ключ кешу transcript-message зі статистики транскриптів SQLite замість викликів stat файлової системи.
- Блокування сеансів середовища виконання та автономну застарілу гілку Doctor для
.jsonl.lockприбрано. - Runtime barrel Microsoft Teams і публічний Plugin SDK більше не реекспортують старий допоміжний засіб file-lock; шляхи довговічного стану Plugin підтримуються SQLite.
- Обрізання за віком/кількістю сеансів і явне очищення сеансів прибрано. Doctor володіє застарілим імпортом; застарілі сеанси скидаються або видаляються явно.
- Перевірки цілісності Doctor більше не рахують застарілий файл JSONL як дійсний активний транскрипт для рядка сеансу SQLite. Справність активного транскрипта є лише SQLite; застарілі файли JSONL повідомляються як вхідні дані для міграції/очищення orphan.
- Doctor більше не вважає
agents/<agent>/sessions/обов’язковим станом середовища виконання. Він сканує цей каталог лише тоді, коли він уже існує, як вхідні дані застарілого імпорту або очищення orphan. sessions.resolveGateway, шляхи patch/reset/compact сеансу, створення субагентів, fast abort, метадані ACP, сеанси, ізольовані Heartbeat, і виправлення TUI більше не мігрують і не обрізають застарілі ключі сеансів як побічний ефект звичайної роботи середовища виконання.- Розв’язання сеансу команди CLI тепер повертає власний
agentIdзамістьstorePath, і більше не копіює застарілі рядки main-session під час звичайного розв’язання--toабо--session-id. Канонізація застарілих main-row належить лише Doctor. - Розв’язання глибини субагента середовища виконання більше не читає
sessions.jsonабо сховища сеансів JSON5. Воно читає SQLitesession_entriesза ідентифікатором агента, а застарілі метадані глибини/сеансу можуть потрапити лише через шлях імпорту Doctor. - Перевизначення сеансів профілю автентифікації зберігаються через прямі upsert рядків
{agentId, sessionKey}замість лінивого завантаження файлового середовища виконання session-store. - Verbose gating автоматичних відповідей і допоміжні засоби оновлення сеансів тепер читають/upsert-ять рядки сеансів SQLite за ідентичністю сеансу й більше не потребують застарілого шляху сховища перед зміною збереженого стану рядків.
- Допоміжні засоби метаданих сеансів command-run тепер використовують entry-орієнтовані імена та шляхи
модулів; стару поверхню допоміжних команд
session-storeприбрано. - Засівання bootstrap header і посилення меж ручного Compaction тепер змінюють
рядки транскриптів SQLite безпосередньо. Виклики середовища виконання передають ідентичність сеансу, а не
записувані шляхи
.jsonl. - Повторне відтворення silent session-rotation копіює останні репліки користувача/асистента за
{agentId, sessionId}з рядків транскриптів SQLite. Воно більше не приймає вихідні або цільові локатори транскриптів. - Нові рядки сеансів середовища виконання більше не зберігають локатори транскриптів. Виклики використовують
{agentId, sessionId}безпосередньо; команди експорту/налагодження можуть вибирати імена вихідних файлів, коли матеріалізують рядки. - Запуск нового збереженого сеансу транскрипта тепер завжди відкриває рядки SQLite за областю. Менеджер сеансів більше не повторно використовує попередній шлях або локатор транскрипта файлової епохи як ідентичність нового сеансу.
- Збережені сеанси транскриптів використовують явний
API
openTranscriptSessionManagerForSession({agentId, sessionId}). Старі статичні фасадиSessionManager.create/openForSession/list/forkFromSessionприбрано, щоб тести й код середовища виконання не могли випадково відтворити виявлення сеансів файлової епохи. - Середовище виконання Plugin більше не надає
api.runtime.agent.session.resolveTranscriptLocatorPath; код Plugin використовує допоміжні засоби рядків SQLite і значення області. - Публічна поверхня SDK
session-store-runtimeтепер експортує лише допоміжні засоби рядків сеансів і рядків транскриптів. Сфокусовані допоміжні засоби schema/path/transaction SQLite живуть уsqlite-runtime; сирі допоміжні засоби open/close/reset залишаються локальними лише для first-party тестів. - Застарілі класифікатори імен файлів траєкторій/контрольних точок
.jsonlтепер живуть у застарілому модулі session-file Doctor. Основна перевірка сеансів більше не імпортує допоміжні засоби file-artifact, щоб визначати звичайні ідентифікатори сеансів SQLite. - Блокувальні запуски субагентів Active Memory використовують рядки транскриптів SQLite замість
створення тимчасових або збережених файлів
session.jsonlу стані Plugin. Старий параметрtranscriptDirприбрано. - Одноразова генерація slug і запуски планувальника Crestodian використовують рядки транскриптів SQLite
замість створення тимчасових файлів
session.jsonl. - Запуски допоміжного засобу
llm-taskі приховане витягування commitment також використовують рядки транскриптів SQLite, тому ці model-only допоміжні сеанси більше не створюють тимчасових файлів транскриптів JSON/JSONL. TranscriptSessionManagerтепер є лише відкритою областю транскрипта SQLite. Код середовища виконання відкриває його черезopenTranscriptSessionManagerForSession({agentId, sessionId}); потоки create, branch, continue, list і fork живуть у відповідних допоміжних засобах рядків SQLite, а не в статичних фасадах менеджера. Код Doctor/import/debug обробляє явні застарілі вихідні файли поза менеджером сеансів середовища виконання.- Застарілі фасадні методи
SessionManager.newSession()іSessionManager.createBranchedSession()було прибрано. Нові сеанси та нащадки транскриптів створюються відповідним робочим процесом SQLite замість зміни вже відкритого менеджера в інший збережений сеанс. - Рішення щодо форку батьківського транскрипта й створення форку більше не приймають
storePathабоsessionsDir; вони використовують область транскрипта SQLite{agentId, sessionId}замість збережених метаданих шляху файлової системи. - Memory-host більше не експортує no-op допоміжні засоби класифікації транскриптів каталогів сеансів; фільтрація транскриптів тепер виводиться з метаданих рядків SQLite під час побудови записів.
- Тести експорту сеансів Memory-host і QMD використовують області транскриптів SQLite. Старі
шляхи
agents/<agentId>/sessions/*.jsonlзалишаються покритими лише там, де тест навмисно доводить сумісність Doctor/import/export. - Сирий огляд сеансів QA-lab тепер використовує
sessions.listчерез gateway замість читанняagents/qa/sessions/sessions.json; відгуки MSteams додаються безпосередньо до транскриптів SQLite без створення штучного шляху JSONL. - Спільні вхідні звернення каналів тепер передають
{agentId, sessionKey}, а не застарілийstorePath. Шляхи запису LINE, WhatsApp, Slack, Discord, Telegram, Matrix, Signal, iMessage, BlueBubbles, Feishu, Google Chat, IRC, Nextcloud Talk, Zalo, Zalo Personal, QA Channel, Microsoft Teams, Mattermost, Synology Chat, Tlon, Twitch і QQBot тепер читають метадані updated-at і записують рядки вхідних сесій через ідентичність SQLite. - Збереження локатора транскрипту видалено з рядків активних сесій.
resolveSessionTranscriptTargetповертаєagentId,sessionIdі необов’язкові метадані теми; doctor — єдиний код, який імпортує застарілі імена файлів транскриптів. - Заголовки транскриптів runtime починаються з версії SQLite
1. Оновлення старих форм JSONL V1/V2/V3 існують лише в імпорті doctor і нормалізують імпортовані заголовки до поточної версії транскриптів SQLite перед збереженням рядків. - Захист database-first тепер забороняє
SessionManager.listAllіSessionManager.forkFromSession; списки сесій і робочі процеси fork/restore мають залишатися на рядкових/обмежених за scope API SQLite. - Захист також забороняє імена застарілих допоміжних функцій розбору JSONL транскриптів/ремонту active-branch поза кодом doctor/import, тож runtime не може отримати другий шлях міграції застарілих транскриптів.
- Вбудовані запуски PI відхиляють вхідні handles транскриптів. Вони використовують ідентичність SQLite
{agentId, sessionId}перед запуском worker і знову перед тим, як спроба торкнеться стану транскрипту. Застарілий вхід/tmp/*.jsonlне може вибрати ціль запису runtime. - Записи трасування кешу, Anthropic payload, raw stream і diagnostics timeline
тепер записуються до типізованих рядків SQLite
diagnostic_events. Пакети стабільності Gateway тепер записуються до типізованих рядків SQLitediagnostic_stability_bundles. Старі шляхи перевизначення JSONLdiagnostics.cacheTrace.filePath,OPENCLAW_CACHE_TRACE_FILE,OPENCLAW_ANTHROPIC_PAYLOAD_LOG_FILEіOPENCLAW_DIAGNOSTICS_TIMELINE_PATHвидалено, а звичайне захоплення стабільності більше не записує файлиlogs/stability/*.json. - Збереження Cron тепер узгоджує рядки SQLite
cron_jobsзамість видалення й повторного вставлення всієї таблиці завдань під час кожного збереження. Зворотні записи цілей Plugin оновлюють відповідні рядки cron напряму й тримають runtime-стан cron у тій самій транзакції бази даних стану. - Викликачі Cron runtime тепер використовують стабільний ключ сховища cron SQLite. Застарілі
шляхи
cron.storeє лише вхідними даними імпорту doctor; production gateway, обслуговування завдань, status, run-log і шляхи зворотного запису цілі Telegram використовуютьresolveCronStoreKeyі більше не нормалізують ключ як шлях. Статус Cron тепер повідомляєstoreKey, а не старе полеstorePathу формі файлу. - Завантаження й планування Cron runtime більше не нормалізують застарілі збережені форми завдань,
як-от
jobId,schedule.cron, числовийatMs, рядкові booleans або відсутнійsessionTarget. Імпорт застарілих даних doctor відповідає за ці ремонти перед вставленням рядків у SQLite. - ACP spawn більше не визначає і не зберігає шляхи файлів JSONL транскриптів. Налаштування spawn і thread-bind зберігає рядок сесії SQLite напряму й залишає id сесії як утриману ідентичність транскрипту.
- API метаданих сесій ACP тепер читають/перелічують/upsert рядки SQLite за
agentIdі більше не відкриваютьstorePathяк частину контракту запису сесії ACP. - Облік використання сесій і агрегація використання Gateway тепер визначають транскрипти
лише за
{agentId, sessionId}. Кеш cost/usage і підсумки знайдених сесій більше не синтезують і не повертають рядки локаторів транскриптів. - Gateway chat append, abort-partial persistence,
/sessions.sendі записи медіа транскриптів webchat додають дані напряму через scope транскрипту SQLite. Допоміжна функція ін’єкції транскрипту Gateway більше не приймає параметрtranscriptLocator. - Виявлення транскриптів SQLite тепер перелічує лише scopes і stats транскриптів:
{agentId, sessionId, updatedAt, eventCount}. Мертву сумісну допоміжну функціюlistSqliteSessionTranscriptLocatorsі полеlocatorдля кожного рядка видалено. - Runtime ремонту транскриптів тепер відкриває лише
repairTranscriptSessionStateIfNeeded({agentId, sessionId}). Стару допоміжну функцію ремонту на основі локатора видалено; код doctor/debug читає явні шляхи вихідних файлів і ніколи не мігрує рядки локаторів. - Runtime replay ledger ACP тепер зберігає рядки replay для кожної сесії у спільній
базі даних стану SQLite замість
acp/event-ledger.json; doctor імпортує й видаляє застарілий файл. - Допоміжні функції читання транскриптів Gateway тепер розміщені в
src/gateway/session-transcript-readers.tsзамість старої назви модуляsession-utils.fs. Перевірка історії fallback retry названа за вмістом транскриптів SQLite, а не за старою поверхнею file-helper. - Допоміжні функції injected-chat і compaction Gateway тепер передають scope транскрипту SQLite через внутрішні helper API замість називання значень шляхами транскриптів або вихідними файлами.
- Виявлення продовження bootstrap тепер перевіряє рядки транскриптів SQLite через
hasCompletedBootstrapTranscriptTurn; воно більше не відкриває helper-ім’я у формі файлу. - Тести embedded-runner тепер використовують ідентичність транскрипту SQLite, а відкриття нового
менеджера транскриптів завжди потребує явного
sessionId. - Допоміжні функції індексації пам’яті тепер наскрізно використовують термінологію транскриптів SQLite:
host експортує
listSessionTranscriptScopesForAgentіsessionTranscriptKeyForScope, цільові черги синхронізаціїsessionTranscripts, публічні результати пошуку сесій відкривають opaque-шляхиtranscript:<agent>:<session>, а внутрішній ключ джерела DB — цеsession:<session>підsource_kind='sessions'замість фальшивого файлового шляху. - Універсальна допоміжна функція persistent-dedupe Plugin SDK більше не відкриває опції у формі файлу. Викликачі надають ключі scope SQLite, а durable dedupe rows живуть у спільному стані Plugin.
- SSO-токени Microsoft Teams перенесено із заблокованих JSON-файлів до стану Plugin SQLite.
Doctor імпортує
msteams-sso-tokens.json, перебудовує канонічні ключі SSO-токенів з payloads і видаляє вихідний файл. Делеговані OAuth-токени залишаються на наявній приватній межі credential-file. - Стан кешу синхронізації Matrix перенесено з
bot-storage.jsonдо стану Plugin SQLite. Doctor імпортує застарілі raw або wrapped sync payloads і видаляє вихідний файл. Активні клієнти Matrix і QA Matrix передають кореневий каталог sync-store SQLite, а не фальшивий шляхsync-store.jsonабоbot-storage.json. - Статус застарілої crypto-міграції Matrix перенесено з
legacy-crypto-migration.jsonдо стану Plugin SQLite. Doctor імпортує старий файл статусу; snapshots IndexedDB Matrix SDK перенесено зcrypto-idb-snapshot.jsonдо blobs Plugin SQLite. Ключі відновлення Matrix і облікові дані є рядками стану Plugin SQLite; їхні старі JSON-файли є лише вхідними даними міграції doctor. - Журнали активності Memory Wiki тепер використовують стан Plugin SQLite замість
.openclaw-wiki/log.jsonl. Провайдер міграції Memory Wiki імпортує старі журнали JSONL; wiki markdown і вміст користувацького vault залишаються file-backed як вміст workspace. - Memory Wiki більше не створює
.openclaw-wiki/state.jsonабо невикористаний каталог.openclaw-wiki/locks. Провайдер міграції видаляє ці виведені з ужитку файли метаданих Plugin, якщо старіший vault усе ще їх має. - Записи аудиту Crestodian тепер використовують core SQLite стан Plugin замість
audit/crestodian.jsonl. Doctor імпортує застарілий журнал аудиту JSONL і видаляє його після успішного імпорту. - Записи аудиту запису/спостереження config тепер використовують core SQLite стан Plugin
замість
logs/config-audit.jsonl. Doctor імпортує застарілий журнал аудиту JSONL і видаляє його після успішного імпорту. - macOS companion більше не записує app-local sidecars
logs/config-audit.jsonlабоlogs/config-health.jsonпід час редагуванняopenclaw.json. Файл config залишається file-backed, snapshots відновлення залишаються поруч із файлом config, а durable стан аудиту/health config належить до сховища SQLite Gateway. - Очікувані схвалення rescue Crestodian тепер використовують core SQLite стан Plugin замість
crestodian/rescue-pending/*.json. Doctor імпортує застарілі файли очікуваних схвалень і видаляє їх після успішного імпорту. - Тимчасовий стан arm Phone Control тепер використовує стан Plugin SQLite замість
plugins/phone-control/armed.json. Doctor імпортує застарілий файл armed-state у namespacephone-control/arm-stateі видаляє файл. - Doctor більше не ремонтує JSONL транскрипти на місці й не створює backup JSONL файли. Він імпортує active branch у SQLite і видаляє застаріле джерело.
- Пошук транскриптів hook session-memory використовує scope-only читання SQLite
{agentId, sessionId}. Його helper більше не приймає і не виводить локатори транскриптів, застарілі читання файлів або опції перезапису файлів. - Прив’язки розмов Codex app-server тепер ключують стан Plugin SQLite за
ключем сесії OpenClaw або явним scope
{agentId, sessionId}. Вони не мають зберігати fallback-прив’язки за шляхом транскрипту. - Читання mirrored-history Codex app-server використовують лише scope транскрипту SQLite; вони не мають відновлювати ідентичність зі шляхів файлів транскриптів.
- Шляхи скидання role-ordering і compaction більше не unlink старі файли транскриптів; reset лише ротує рядок сесії SQLite та ідентичність транскрипту.
- Відповіді reset і checkpoint Gateway повертають чисті рядки сесій плюс session ids. Вони більше не синтезують локатори транскриптів SQLite для клієнтів.
- Dreaming memory-core більше не обрізає рядки сесій через перевірку відсутніх
JSONL-файлів. Очищення subagent проходить через session runtime API замість
перевірок існування файлової системи. Його тести transcript-ingestion seed рядки SQLite
напряму замість створення fixtures
agents/<id>/sessionsабо placeholders локаторів. - Індексація транскриптів пам’яті може відкривати
transcript:<agentId>:<sessionId>як віртуальний шлях результату пошуку для helpers цитування/читання. Durable index source є relational (source_kind='sessions',source_key='session:<sessionId>',session_id=<sessionId>), тож значення не є runtime локатором транскрипту, не є шляхом файлової системи й ніколи не має передаватися назад у session runtime APIs. - Статус пам’яті Gateway doctor читає short-term recall і лічильники phase-signal
з рядків стану Plugin SQLite замість
memory/.dreams/*.json; вивід CLI і doctor тепер позначає це сховище як SQLite store, а не як path. - Runtime memory-core, CLI status, методи Gateway doctor і facades Plugin SDK
більше не аудіюють і не архівують застарілі файли
.dreams/session-corpus. Ці файли є лише вхідними даними міграції; doctor імпортує їх у SQLite і видаляє джерело після перевірки. Активні рядки evidence session-ingestion тепер використовують віртуальний шлях SQLitememory/session-ingestion/<day>.txt; runtime ніколи не записує і не виводить стан з.dreams/session-corpus. - Публічні артефакти memory-core відкривають host events SQLite як віртуальний JSON
артефакт
memory/events/memory-host-events.json; вони більше не використовують повторно застарілий шлях джерела.dreams/events.jsonl. - Реєстри sandbox container/browser тепер використовують спільну таблицю SQLite
sandbox_registry_entriesз типізованими стовпцями session, image, timestamp, backend/config і browser port. Doctor імпортує застарілі монолітні та sharded JSON registry files і видаляє успішні джерела. Runtime reads використовують типізовані стовпці рядків як source of truth;entry_jsonє лише replay/debug копією. - Commitments тепер використовують типізовану спільну таблицю
commitmentsзамість whole-store JSON blob. Snapshot saves виконують upsert за commitment id і видаляють лише відсутні рядки замість очищення й повторного вставлення таблиці. Runtime loads commitments з типізованих стовпців scope, delivery-window, status, attempt і text;record_jsonє лише replay/debug копією. Doctor імпортує застарілийcommitments.jsonі видаляє його після успішного імпорту. - Визначення завдань Cron, стан schedule і історія запусків більше не мають runtime
JSON writers або readers. Runtime використовує рядки
cron_jobsз типізованим schedule, payload, delivery, failure-alert, session, status і стовпці runtime-state, а також типізовані метаданіcron_run_logsдля статусу, діагностичного підсумку, статусу/помилки доставки, session/run, model і загальних token totals.job_jsonє лише копією для replay/debug;state_jsonзберігає вкладену runtime-діагностику, яка ще не має полів для hot-запитів, тоді як runtime регідратує hot-поля стану з типізованих стовпців. Doctor імпортує застарілі файлиjobs.json,jobs-state.jsonіruns/*.jsonlта видаляє імпортовані джерела. Зворотні записи цілей Plugin оновлюють відповідні рядкиcron_jobsзамість завантаження й заміни всього cron-сховища. - Запуск Gateway ігнорує застарілі маркери
notify: trueу runtime-проєкції. Doctor перетворює їх на явну доставку SQLite, колиcron.webhookє дійсним, видаляє інертні маркери, коли його не задано, і зберігає їх із попередженням, коли налаштований webhook недійсний. - Черги вихідної доставки та доставки session тепер зберігають статус черги, тип запису,
ключ session, channel, target, account id, кількість повторних спроб, останню спробу/помилку,
стан recovery і маркери platform-send як типізовані стовпці у спільній
таблиці
delivery_queue_entries. Runtime recovery читає ці hot-поля з типізованих стовпців, а мутації retry/recovery оновлюють ці стовпці напряму без переписування replay JSON. Повний JSON payload залишається лише як replay/debug blob для тіл повідомлень та інших cold replay даних. - Керовані записи вихідних зображень тепер використовують типізовані спільні
рядки
managed_outgoing_image_records, а media bytes і далі зберігаються вmedia_blobs. JSON-запис залишається лише як копія для replay/debug. - Налаштування model-picker Discord, хеші command-deploy і прив’язки thread тепер використовують спільний SQLite-стан Plugin. Їхні плани імпорту застарілого JSON містяться на поверхні setup/doctor migration Plugin Discord, а не в коді міграції core.
- Детектори застарілих імпортів Plugin використовують doctor-названі модулі, як-от
doctor-legacy-state.tsабоdoctor-state-imports.ts; звичайні runtime-модулі channel не повинні імпортувати детектори застарілого JSON. - Курсори catchup BlueBubbles і вхідні маркери dedupe тепер використовують спільний SQLite-стан Plugin. Їхні плани імпорту застарілого JSON містяться на поверхні setup/doctor migration Plugin BlueBubbles, а не в коді міграції core.
- Зсуви оновлень Telegram, рядки sticker cache, рядки sent-message cache, рядки topic-name cache і прив’язки thread тепер використовують спільний SQLite-стан Plugin. Їхні плани імпорту застарілого JSON містяться на поверхні setup/doctor migration Plugin Telegram, а не в коді міграції core.
- Курсори catchup iMessage, мапінги reply short-id і рядки sent-echo dedupe
тепер використовують спільний SQLite-стан Plugin. Старі файли
imessage/catchup/*.json,imessage/reply-cache.jsonlіimessage/sent-echoes.jsonlє лише вхідними даними doctor. - Рядки dedupe повідомлень Feishu тепер використовують спільний SQLite-стан Plugin замість
файлів
feishu/dedup/*.json. Його план імпорту застарілого JSON міститься на поверхні setup/doctor migration Plugin Feishu, а не в коді міграції core. - Розмови Microsoft Teams, опитування, буфери pending upload і feedback
learnings тепер використовують спільні таблиці SQLite plugin state/blob. Шлях pending upload
використовує
plugin_blob_entries, тому медіабуфери зберігаються як SQLite BLOB замість base64 JSON. Назви runtime-помічників тепер використовують іменування SQLite/state, а не іменування файлового сховища*-fs, і старий shimstorePathвилучено з цих сховищ. Його план імпорту застарілого JSON міститься на поверхні setup/doctor migration Plugin Microsoft Teams. - Розміщені вихідні media Zalo тепер використовують спільний SQLite
plugin_blob_entriesзамість тимчасових JSON/bin sidecaropenclaw-zalo-outbound-media. - HTML і метадані переглядача diff тепер використовують спільний SQLite
plugin_blob_entriesзамість тимчасових файлівmeta.json/viewer.html. Згенеровані PNG/PDF outputs залишаються тимчасовими матеріалізаціями, бо доставка channel все ще потребує file path. - Керовані документи Canvas тепер використовують спільний SQLite
plugin_blob_entriesзамість стандартного каталогуstate/canvas/documents. Хост Canvas віддає ці blobs напряму; локальні файли створюються лише для явного операторського вмістуhost.rootабо тимчасової матеріалізації, коли нижчий media reader потребує path. - Рішення audit File Transfer тепер використовують спільний SQLite
plugin_state_entriesзамість необмеженого runtime-журналуaudit/file-transfer.jsonl. Doctor імпортує застарілий JSONL audit-файл у стан Plugin і видаляє джерело після чистого імпорту. - Лізи процесів ACPX і ідентичність екземпляра Gateway тепер використовують спільний SQLite-стан Plugin.
Doctor імпортує застарілий файл
gateway-instance-idу стан Plugin і видаляє джерело. - Згенеровані wrapper scripts ACPX і ізольований Codex home є тимчасовою
матеріалізацією під temp root OpenClaw, а не довговічним станом OpenClaw. Довговічні
runtime-записи ACPX - це рядки SQLite lease і gateway-instance;
стару поверхню конфігурації ACPX
stateDirвилучено, бо runtime-стан туди більше не записується. - Media attachments Gateway тепер використовують спільну таблицю SQLite
media_blobsяк канонічне byte store. Локальні paths, повернені до channel і sandbox compatibility surfaces, є тимчасовими матеріалізаціями database row, а не довговічним media store. Runtime media allowlists більше не містять застарілі корені$OPENCLAW_STATE_DIR/mediaабо config-dirmedia; ці каталоги є лише джерелами імпорту doctor. - Shell completion більше не записує cache-файли
$OPENCLAW_STATE_DIR/completions/*. Шляхи install, doctor, update і release smoke використовують згенерований completion output або profile sourcing замість довговічних completion cache файлів. - Staging skill-upload Gateway тепер використовує спільні рядки
skill_uploads. Upload metadata, idempotency keys і archive bytes зберігаються в SQLite; installer отримує лише тимчасово матеріалізований archive path, доки триває install. - Inline attachments subagent більше не матеріалізуються під workspace
.openclaw/attachments/*. Шлях spawn готує seed-записи SQLite VFS, inline runs засівають ці записи в per-agent runtime scratch namespace, а disk-backed tools накладають цей SQLite scratch для attachment paths. Старі registry columns attachment-dir для subagent-run і cleanup hooks вилучено. - Гідратація CLI image більше не підтримує стабільні cache-файли
openclaw-cli-images. Зовнішні CLI backends усе ще отримують file paths, але ці paths є per-run temp materializations із cleanup. - Діагностика cache-trace, діагностика Anthropic payload, діагностика raw model stream,
diagnostics timeline events і stability bundles Gateway тепер
записують рядки SQLite замість файлів
logs/*.jsonlабоlogs/stability/*.json. Runtime path override flags і env vars вилучено; команди export/debug можуть явно матеріалізувати файли з database rows. - macOS companion більше не має rolling writer
diagnostics.jsonl. App logs ідуть у unified logging, а довговічна діагностика Gateway лишається SQLite-backed. - Список записів macOS port-guardian тепер використовує типізовані спільні SQLite
рядки
macos_port_guardian_recordsзамість JSON-файлу Application Support або непрозорого singleton blob. - Singleton locks Gateway тепер використовують типізовані спільні SQLite-рядки
state_leasesпід scopegateway_locksзамість lock-файлів у temp-dir. Документи Fly і OAuth troubleshooting тепер вказують на SQLite lease/auth refresh lock замість застарілого очищення file-lock. - Restart sentinel state Gateway тепер використовує типізовані спільні SQLite
рядки
gateway_restart_sentinelзамістьrestart-sentinel.json; runtime читає sentinel kind, status, routing, message, continuation і stats з типізованих стовпців.payload_jsonє лише копією replay/debug. Runtime code очищає SQLite row напряму й більше не містить plumbing cleanup файлів. - Restart intent Gateway і supervisor handoff state тепер використовують типізовані спільні
SQLite рядки
gateway_restart_intentіgateway_restart_handoffзамість sidecar-файлівgateway-restart-intent.jsonіgateway-supervisor-restart-handoff.json. - Singleton coordination Gateway тепер використовує типізовані рядки
state_leasesпідgateway_locksзамість запису файлівgateway.<hash>.lock. Рядок lease володіє lock owner, expiry, Heartbeat і debug payload; SQLite володіє atomic acquire/release boundary. Retired file-lock directory option вилучено; тести використовують SQLite row identity напряму. - Старий unused cron usage-report helper, який сканував файли
cron/runs/*.jsonl, було видалено. Звіти Cron run history мають читати типізовані SQLite-рядкиcron_run_logs. - Main-session restart recovery тепер знаходить candidate agents через
SQLite-реєстр
agent_databasesзамість сканування каталогівagents/*/sessions. - Gemini session-corruption recovery тепер видаляє лише SQLite session row;
йому більше не потрібен застарілий gate
storePath, і він не намагається unlink derived transcript JSONL path. - Обробка Path override тепер трактує буквальні env values
undefined/nullяк unset, запобігаючи випадковим repo-root базам данихundefined/state/*.sqliteпід час tests або shell handoffs. - Config health fingerprints тепер використовують типізовані спільні SQLite-рядки
config_health_entriesзамістьlogs/config-health.json, залишаючи звичайний config file єдиним non-credential configuration document. macOS companion зберігає лише process-local health state і не відтворює старий JSON sidecar. - Runtime auth profile більше не імпортує й не записує credential JSON files. Канонічним
credential store є SQLite;
auth-profiles.json, per-agentauth.jsonі спільнийcredentials/oauth.jsonє вхідними даними doctor migration, які видаляються після імпорту. - Тести save/state для auth profile тепер напряму перевіряють типізовані SQLite auth tables і використовують застарілі auth-profile filenames лише для входів doctor migration.
openclaw secrets applyочищає лише config file, env file і SQLite auth-profile store. Він більше не містить compatibility logic, що редагує retired per-agentauth.json; doctor відповідає за імпорт і видалення цього файлу.- Плани Hermes secret migration і applies імпортували API-key profiles напряму
в SQLite auth-profile store. Він більше не записує й не перевіряє
auth-profiles.jsonяк проміжну ціль. - User-facing auth docs тепер описують
state/openclaw.sqlite#table/auth_profile_stores/<agentDir>замість інструкцій користувачам inspect або copyauth-profiles.json; застарілі назви OAuth/auth JSON залишаються задокументованими лише як doctor-import inputs. - Core state-path helpers більше не expose retired файл
credentials/oauth.json. Застаріле filename є локальним для doctor auth import path. - Документи install, security, onboarding, model-auth і SecretRef тепер описують SQLite auth-profile rows і whole-state backup/migration замість per-agent auth-profile JSON files.
- PI model discovery тепер передає canonical credentials у in-memory
auth storage
pi-coding-agent. Він більше не створює, не очищає й не записує per-agentauth.jsonпід час discovery. - Налаштування Voice Wake trigger і routing тепер використовують типізовані спільні таблиці SQLite
замість
settings/voicewake.json,settings/voicewake-routing.jsonабо opaque generic rows; doctor імпортує застарілі JSON-файли та видаляє їх після successful migration. - Update-check state тепер використовує типізований спільний рядок
update_check_stateзамістьupdate-check.jsonабо opaque generic blob; doctor імпортує застарілий JSON-файл і видаляє його після successful migration. - Config health state тепер використовує типізовані спільні рядки
config_health_entriesзамістьlogs/config-health.jsonабо opaque generic blob; doctor імпортує застарілий JSON-файл і видаляє його після successful migration. - Plugin conversation binding approvals тепер використовують типізовані
рядки
plugin_binding_approvalsзамість opaque shared SQLite state абоplugin-binding-approvals.json; застарілий файл є вхідними даними для міграції doctor. - Загальні прив’язки поточної розмови тепер зберігають типізовані рядки
current_conversation_bindingsзамість перезаписуbindings/current-conversations.json; doctor імпортує застарілий JSON-файл і видаляє його після успішної міграції. - Журнали синхронізації імпортованих джерел Memory Wiki тепер зберігають один
рядок стану Plugin у SQLite на ключ сховища/джерела замість перезапису
.openclaw-wiki/source-sync.json; провайдер міграції імпортує та видаляє застарілий JSON-журнал. - Записи запусків імпорту ChatGPT у Memory Wiki тепер зберігають один рядок
стану Plugin у SQLite на ідентифікатор сховища/запуску замість запису
.openclaw-wiki/import-runs/*.json. Знімки для відкату залишаються явними файлами сховища, доки архівацію знімків запусків імпорту не буде перенесено до сховища blob-об’єктів. - Скомпільовані дайджести Memory Wiki тепер зберігають рядки blob-об’єктів
Plugin у SQLite замість запису
.openclaw-wiki/cache/agent-digest.jsonі.openclaw-wiki/cache/claims.jsonl. Провайдер міграції імпортує старі файли кешу та видаляє каталог кешу, коли він стає порожнім. - Відстеження встановлення Skills у ClawHub тепер зберігає один рядок стану
Plugin у SQLite на робочу область/Skill замість запису або читання супровідних
файлів
.clawhub/lock.jsonі.clawhub/origin.jsonпід час виконання. Код середовища виконання використовує об’єкти стану відстежених встановлень, а не абстракції lockfile/origin у формі файлів. Doctor імпортує застарілі супровідні файли з налаштованих робочих областей агентів і видаляє їх після чистого імпорту. - Індекс установлених Plugin тепер читає та записує типізований спільний
singleton-рядок SQLite
installed_plugin_indexзамістьplugins/installs.json; застарілий JSON-файл є лише вхідними даними для міграції doctor і видаляється після імпорту. - Застарілий допоміжний засіб шляху
plugins/installs.jsonтепер живе в застарілому коді doctor. Модулі індексу Plugin у середовищі виконання надають лише параметри збереження на базі SQLite, а не шлях до JSON-файлу. - Sentinel перезапуску Gateway, намір перезапуску та стан передавання
supervisor тепер використовують типізовані спільні рядки SQLite
(
gateway_restart_sentinel,gateway_restart_intentіgateway_restart_handoff) замість загальних opaque blob-об’єктів. Код перезапуску середовища виконання не має контракту sentinel/intent/handoff у формі файлів. - Кеш синхронізації Matrix, метадані сховища, прив’язки потоків, маркери
дедуплікації вхідних подій, стан cooldown для перевірки запуску, криптографічні
знімки SDK IndexedDB, облікові дані та ключі відновлення тепер використовують
спільні таблиці стану/blob-об’єктів Plugin у SQLite. Структури шляхів
середовища виконання більше не надають шлях метаданих
storage-meta.json; ця назва файлу є лише вхідними даними застарілої міграції. Їхній план імпорту застарілого JSON живе в поверхні налаштування/міграції doctor Plugin Matrix. - Запуск Matrix більше не сканує, не звітує і не завершує застарілий файловий стан Matrix. Виявлення файлів Matrix, створення застарілого криптографічного знімка, стан міграції відновлення room-key, імпорт і видалення джерела повністю належать doctor.
- Runtime barrels міграції Matrix було видалено. Допоміжні засоби виявлення та зміни застарілого стану/криптографії імпортуються doctor Matrix напряму, замість того щоб бути частиною runtime API.
- Маркери повторного використання знімків міграції Matrix тепер живуть у стані
Plugin SQLite замість
matrix/migration-snapshot.json; doctor усе ще може повторно використовувати той самий перевірений передміграційний архів без запису супровідного файлу стану. - Курсори шини Nostr і стан публікації профілю тепер використовують спільний стан Plugin у SQLite. Їхній план імпорту застарілого JSON живе в поверхні налаштування/міграції doctor Plugin Nostr.
- Перемикачі сесій Active Memory тепер використовують спільний стан Plugin у
SQLite замість
session-toggles.json; повторне ввімкнення пам’яті видаляє рядок замість перезапису JSON-об’єкта. - Пропозиції Skill Workshop і лічильники review тепер використовують спільний
стан Plugin у SQLite замість сховищ
skill-workshop/<workspace>.jsonдля кожної робочої області. Кожна пропозиція є окремим рядком уskill-workshop/proposals, а лічильник review є окремим рядком уskill-workshop/reviews. - Запуски subagent reviewer у Skill Workshop тепер використовують resolver
transcript сесії середовища виконання замість створення супровідних шляхів
сесій
skill-workshop/<sessionId>.json. - Оренди процесів ACPX тепер використовують спільний стан Plugin у SQLite під
acpx/process-leasesзамість реєстру цілого файлуprocess-leases.json. Кожна оренда зберігається як власний рядок, зберігаючи прибирання застарілих процесів під час запуску без runtime-шляху перезапису JSON. - Wrapper-скрипти ACPX та ізольований home Codex генеруються в тимчасовому корені OpenClaw. Вони перестворюються за потреби й не є вхідними даними для резервного копіювання або міграції.
- Збереження реєстру запусків subagent використовує типізовані спільні рядки
subagent_runs. Старий шляхsubagents/runs.jsonтепер є лише вхідними даними для міграції doctor, а назви runtime-допоміжних засобів більше не описують шар стану як disk-backed. Runtime-тести більше не створюють недійсні або порожні фікстуриruns.jsonдля доведення поведінки реєстру; вони напряму засівають/читають рядки SQLite. - Резервне копіювання готує каталог стану перед архівацією, копіює
недатабазні файли, створює знімки баз даних
*.sqliteчерезVACUUM INTO, пропускає live-супровідні файли WAL/SHM, записує метадані знімків у маніфест архіву та записує завершені запуски резервного копіювання в SQLite разом із маніфестом архіву.openclaw backup createза замовчуванням перевіряє записаний архів;--no-verifyє явним швидким шляхом. openclaw backup restoreперевіряє архів перед видобуванням, повторно використовує нормалізований маніфест verifier і відновлює перевірені ресурси маніфесту до записаних для них вихідних шляхів. Для запису потрібен--yes, а для плану відновлення підтримується--dry-run.- Старий фільтр volatile-path для резервного копіювання видалено. Резервному копіюванню більше не потрібен live-tar skip list для застарілих JSON/JSONL файлів сесій або cron, оскільки знімки SQLite готуються до створення архіву.
- Plain setup і підготовка робочої області onboarding більше не створюють
каталоги
agents/<agentId>/sessions/. Вони створюють лише config/робочу область; рядки сесій SQLite і рядки transcript створюються на вимогу в базі даних конкретного агента. - Виправлення дозволів безпеки тепер націлюється на глобальну та агентні бази
даних SQLite разом із супровідними файлами WAL/SHM замість
sessions.jsonі JSONL-файлів transcript. - Runtime-назви реєстру sandbox тепер описують види реєстру SQLite напряму замість перенесення застарілої термінології JSON-реєстру через активне сховище.
openclaw reset --scope config+creds+sessionsвидаляє агентні бази данихopenclaw-agent.sqliteразом із супровідними файлами WAL/SHM, а не лише застарілі каталогиsessions/.- Допоміжні засоби aggregate session Gateway тепер використовують назви,
орієнтовані на записи:
loadCombinedSessionEntriesForGatewayповертає{ databasePath, entries }. Стару combined-store naming було видалено з runtime-викликачів. - Засівання Docker MCP channel тепер записує основний рядок сесії та події
transcript у агентну базу даних SQLite замість створення
sessions.jsonі JSONL transcript. - Вбудований hook session-memory тепер визначає контекст попередньої сесії з
SQLite за
{agentId, sessionId}. Він більше не сканує, не зберігає і не синтезує шляхи transcript або каталогиworkspace/sessions. - Вбудований hook command-logger тепер записує рядки аудиту команд до спільної
таблиці SQLite
command_log_entriesзамість додавання доlogs/commands.log. - Allowlist для pairing каналів тепер надають лише допоміжні засоби
читання/запису на базі SQLite у середовищі виконання та plugin SDK. Старий
resolver шляху
*-allowFrom.jsonі reader файлу живуть лише в застарілому коді імпорту doctor. migration_runsзаписує виконання міграцій застарілого стану зі статусом, часовими мітками та JSON-звітами.migration_sourcesзаписує кожне імпортоване джерело застарілого файлу з hash, розміром, кількістю записів, цільовою таблицею, run id, статусом і станом видалення джерела.backup_runsзаписує шляхи архівів резервного копіювання, статус і JSON маніфести.- Глобальна схема не зберігає невикористану таблицю реєстру
agents. Виявлення баз даних агентів є канонічним реєстромagent_databases, доки runtime не матиме реального власника agent-record. - Згенерована config каталогу моделей зберігається в типізованих глобальних
рядках SQLite
agent_model_catalogs, ключованих за каталогом агента. Runtime-викликачі використовуютьensureOpenClawModelCatalog; у runtime-коді немає API сумісностіmodels.json. Реалізація записує SQLite, а вбудований PI registry гідратується з цього збереженого payload без створення файлуmodels.json. - Markdown-експорт transcript сесій QMD і config
memory.qmd.sessionsбуло видалено. Немає колекції transcript QMD, немає runtime-шляхуqmd/sessions*і немає file-backed bridge пам’яті сесій. - Runtime memory-core імпортує допоміжні засоби індексації SQLite transcript з
openclaw/plugin-sdk/memory-core-host-engine-session-transcripts, а не з підшляху QMD SDK. Підшлях QMD зберігає compatibility re-export лише для зовнішніх викликачів, доки major cleanup SDK не зможе його видалити. - Власний
index.sqliteQMD тепер є тимчасовою runtime-матеріалізацією на базі основної таблиці SQLiteplugin_blob_entries. Runtime більше не створює довговічний супровідний файл~/.openclaw/agents/<agentId>/qmd. - Необов’язковий Plugin
memory-lancedbбільше не створює~/.openclaw/memory/lancedbяк неявне кероване OpenClaw сховище. Це зовнішній backend LanceDB, і він лишається вимкненим, доки operator не налаштує явнийdbPath. check:database-first-legacy-storesзавершується з помилкою для нового runtime source, який поєднує назви застарілих сховищ із write-style API файлової системи. Він також завершується з помилкою для runtime source, який повторно вводить retired markers моста transcripttranscriptLocatorабоsqlite-transcript://.... Код міграції, doctor, імпорту та явного експорту, не пов’язаного із сесіями, залишається дозволеним. Ширші назви застарілих контрактів, як-отsessionFile,storePathі старі file-era фасадиSessionManager, усе ще мають поточних власників і потребують окремої роботи над guard міграції, перш ніж вони зможуть стати обов’язковою preflight перевіркою. Guard тепер також охоплює runtime-сховищаcache/*.json, загальні супровідні файлиthread-bindings.json, JSON стану/run-log cron, JSON health config, супровідні файли restart і lock, налаштування Voice Wake, затвердження прив’язок Plugin, JSON індексу встановлених Plugin, JSONL аудиту File Transfer, activity logs Memory Wiki, старий текстовий log вбудованогоcommand-loggerі ручки JSONL діагностики raw-stream pi-mono. Він також забороняє старі назви root-level doctor legacy module, щоб код сумісності залишався підsrc/commands/doctor/. Android debug handlers також використовують logcat/in-memory output замість підготовки cache-файлівcamera_debug.logабоdebug_logs.txt.
Цільова форма схеми
Зберігайте схеми явними. Стан runtime, яким володіє хост, використовує типізовані таблиці. Непрозорий стан, яким володіє Plugin,
використовує plugin_state_entries / plugin_blob_entries; універсальної
таблиці хоста kv немає.
Глобальна база даних:
state_leases(scope, lease_key, owner, expires_at, heartbeat_at, payload_json, created_at, updated_at)exec_approvals_config(config_key, raw_json, socket_path, has_socket_token, default_security, default_ask, default_ask_fallback, auto_allow_skills, agent_count, allowlist_count, updated_at_ms)schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)agent_databases(agent_id, path, schema_version, last_seen_at, size_bytes)task_runs(...)task_delivery_state(...)flow_runs(...)subagent_runs(run_id, child_session_key, requester_session_key, controller_session_key, created_at, ended_at, cleanup_handled, payload_json)current_conversation_bindings(binding_key, binding_id, target_agent_id, target_session_id, target_session_key, channel, account_id, conversation_kind, parent_conversation_id, conversation_id, target_kind, status, bound_at, expires_at, metadata_json, updated_at)plugin_binding_approvals(plugin_root, channel, account_id, plugin_id, plugin_name, approved_at)tui_last_sessions(scope_key, session_key, updated_at)plugin_state_entries(plugin_id, namespace, entry_key, value_json, created_at, expires_at)plugin_blob_entries(plugin_id, namespace, entry_key, metadata_json, blob, created_at, expires_at)media_blobs(subdir, id, content_type, size_bytes, blob, created_at, updated_at)skill_uploads(upload_id, kind, slug, force, size_bytes, sha256, actual_sha256, received_bytes, archive_blob, created_at, expires_at, committed, committed_at, idempotency_key_hash)web_push_subscriptions(endpoint_hash, subscription_id, endpoint, p256dh, auth, created_at_ms, updated_at_ms)web_push_vapid_keys(key_id, public_key, private_key, subject, updated_at_ms)apns_registrations(node_id, transport, token, relay_handle, send_grant, installation_id, topic, environment, distribution, token_debug_suffix, updated_at_ms)node_host_config(config_key, version, node_id, token, display_name, gateway_host, gateway_port, gateway_tls, gateway_tls_fingerprint, updated_at_ms)device_identities(identity_key, device_id, public_key_pem, private_key_pem, created_at_ms, updated_at_ms)device_auth_tokens(device_id, role, token, scopes_json, updated_at_ms)macos_port_guardian_records(pid, port, command, mode, timestamp)workspace_setup_state(workspace_key, workspace_path, version, bootstrap_seeded_at, setup_completed_at, updated_at)native_hook_relay_bridges(relay_id, pid, hostname, port, token, expires_at_ms, updated_at_ms)model_capability_cache(provider_id, model_id, name, input_text, input_image, reasoning, supports_tools, context_window, max_tokens, cost_input, cost_output, cost_cache_read, cost_cache_write, updated_at_ms)agent_model_catalogs(catalog_key, agent_dir, raw_json, updated_at)managed_outgoing_image_records(attachment_id, session_key, message_id, created_at, updated_at, retention_class, alt, original_media_id, original_media_subdir, original_content_type, original_width, original_height, original_size_bytes, original_filename, record_json)gateway_restart_sentinel(sentinel_key, version, kind, status, ts, session_key, thread_id, delivery_channel, delivery_to, delivery_account_id, message, continuation_json, doctor_hint, stats_json, payload_json, updated_at_ms)channel_pairing_requests(channel_key, account_id, request_id, code, created_at, last_seen_at, meta_json)channel_pairing_allow_entries(channel_key, account_id, entry, sort_order, updated_at)voicewake_triggers(config_key, position, trigger, updated_at_ms)voicewake_routing_config(config_key, version, default_target_mode, default_target_agent_id, default_target_session_key, updated_at_ms)voicewake_routing_routes(config_key, position, trigger, target_mode, target_agent_id, target_session_key, updated_at_ms)update_check_state(state_key, last_checked_at, last_notified_version, last_notified_tag, last_available_version, last_available_tag, auto_install_id, auto_first_seen_version, auto_first_seen_tag, auto_first_seen_at, auto_last_attempt_version, auto_last_attempt_at, auto_last_success_version, auto_last_success_at, updated_at_ms)config_health_entries(config_path, last_known_good_json, last_promoted_good_json, last_observed_suspicious_signature, updated_at_ms)sandbox_registry_entries(registry_kind, container_name, session_key, backend_id, runtime_label, image, created_at_ms, last_used_at_ms, config_label_kind, config_hash, cdp_port, no_vnc_port, entry_json, updated_at)cron_run_logs(store_key, job_id, seq, ts, status, error, summary, diagnostics_summary, delivery_status, delivery_error, delivered, session_id, session_key, run_id, run_at_ms, duration_ms, next_run_at_ms, model, provider, total_tokens, entry_json, created_at)cron_jobs(store_key, job_id, name, description, enabled, delete_after_run, created_at_ms, agent_id, session_key, schedule_kind, schedule_expr, schedule_tz, every_ms, anchor_ms, at, stagger_ms, session_target, wake_mode, payload_kind, payload_message, payload_model, payload_fallbacks_json, payload_thinking, payload_timeout_seconds, payload_allow_unsafe_external_content, payload_external_content_source_json, payload_light_context, payload_tools_allow_json, delivery_mode, delivery_channel, delivery_to, delivery_thread_id, delivery_account_id, delivery_best_effort, failure_delivery_mode, failure_delivery_channel, failure_delivery_to, failure_delivery_account_id, failure_alert_disabled, failure_alert_after, failure_alert_channel, failure_alert_to, failure_alert_cooldown_ms, failure_alert_include_skipped, failure_alert_mode, failure_alert_account_id, next_run_at_ms, running_at_ms, last_run_at_ms, last_run_status, last_error, last_duration_ms, consecutive_errors, consecutive_skipped, schedule_error_count, last_delivery_status, last_delivery_error, last_delivered, last_failure_alert_at_ms, job_json, state_json, runtime_updated_at_ms, schedule_identity, sort_order, updated_at)delivery_queue_entries(queue_name, id, status, entry_kind, session_key, channel, target, account_id, retry_count, last_attempt_at, last_error, recovery_state, platform_send_started_at, entry_json, enqueued_at, updated_at, failed_at)commitments(id, agent_id, session_key, channel, account_id, recipient_id, thread_id, sender_id, kind, sensitivity, source, status, reason, suggested_text, dedupe_key, confidence, due_earliest_ms, due_latest_ms, due_timezone, source_message_id, source_run_id, created_at_ms, updated_at_ms, attempts, last_attempt_at_ms, sent_at_ms, dismissed_at_ms, snoozed_until_ms, expired_at_ms, record_json)migration_runs(id, started_at, finished_at, status, report_json)migration_sources(source_key, migration_kind, source_path, target_table, source_sha256, source_size_bytes, source_record_count, last_run_id, status, imported_at, removed_source, report_json)backup_runs(id, created_at, archive_path, status, manifest_json)База даних агента:
schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)sessions(session_id, session_key, session_scope, created_at, updated_at, started_at, ended_at, status, chat_type, channel, account_id, primary_conversation_id, model_provider, model, agent_harness_id, parent_session_key, spawned_by, display_name)conversations(conversation_id, channel, account_id, kind, peer_id, parent_conversation_id, thread_id, native_channel_id, native_direct_user_id, label, metadata_json, created_at, updated_at)session_conversations(session_id, conversation_id, role, first_seen_at, last_seen_at)session_routes(session_key, session_id, updated_at)session_entries(session_id, session_key, entry_json, updated_at)transcript_events(session_id, seq, event_json, created_at)transcript_event_identities(session_id, event_id, seq, event_type, has_parent, parent_id, message_idempotency_key, created_at)transcript_snapshots(session_id, snapshot_id, reason, event_count, created_at, metadata_json)vfs_entries(namespace, path, kind, content_blob, metadata_json, updated_at)tool_artifacts(run_id, artifact_id, kind, metadata_json, blob, created_at)run_artifacts(run_id, path, kind, metadata_json, blob, created_at)trajectory_runtime_events(session_id, run_id, seq, event_json, created_at)memory_index_meta(key, value)memory_index_sources(path, source, hash, mtime, size)memory_index_chunks(id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)memory_embedding_cache(provider, model, provider_key, hash, embedding, dims, updated_at)memory_index_state(id, revision)cache_entries(scope, key, value_json, blob, expires_at, updated_at)Майбутній пошук може додати таблиці FTS без зміни канонічних таблиць подій:
transcript_events_fts(session_id, seq, text)vfs_entries_fts(namespace, path, text)Великі значення мають використовувати стовпці blob, а не кодування JSON-рядком. Зберігайте
value_json для малих структурованих даних, які мають залишатися доступними для перегляду звичайними
інструментами SQLite.
agent_databases є канонічним реєстром для цієї гілки. Не додавайте
таблицю agents, доки не з’явиться реальний власник записів агентів; конфігурація агентів залишається в
openclaw.json.
Форма міграції doctor
Doctor має викликати один явний крок міграції, який можна відзвітувати та безпечно повторно запускати:
openclaw doctor --fixopenclaw doctor --fix викликає реалізацію міграції стану після
звичайної попередньої перевірки конфігурації та створює перевірену резервну копію перед імпортом. Запуск runtime
і openclaw migrate не повинні імпортувати застарілі файли стану OpenClaw.
Властивості міграції:
- Один прохід міграції виявляє всі застарілі файлові джерела та створює план перед будь-якими змінами.
- Doctor створює перевірений архів резервної копії перед міграцією до імпортування застарілих файлів.
- Імпорти є ідемпотентними та прив’язані до шляху джерела, mtime, розміру, хешу й цільової таблиці.
- Успішно оброблені файли джерел видаляються або архівуються після того, як цільова база даних виконає commit.
- Невдалі імпорти залишають джерело без змін і записують попередження в
migration_runs. - Код runtime читає лише SQLite після появи міграції.
- Шлях downgrade/export-to-runtime-files не потрібен.
Інвентаризація міграції
Перемістіть це до глобальної бази даних:
- Записи середовища виконання реєстру завдань тепер використовують спільну базу даних; невідвантажений
імпортер sidecar
tasks/runs.sqliteвидалено. Збереження знімків виконують upsert за id завдання і видаляють лише відсутні рядки завдань/доставлення. - Записи середовища виконання Task Flow тепер використовують спільну базу даних; невідвантажений
імпортер sidecar
tasks/flows/registry.sqliteвидалено. Збереження знімків виконують upsert за id потоку і видаляють лише відсутні рядки потоків. - Записи середовища виконання стану Plugin тепер використовують спільну базу даних; невідвантажений
імпортер sidecar
plugin-state/state.sqliteвидалено. - Вбудований пошук пам’яті більше не використовує
memory/<agentId>.sqliteза замовчуванням; його таблиці індексу живуть у базі даних власного агента, а явний sidecar opt-inmemorySearch.store.pathперенесено до міграції конфігурації doctor. - Переіндексація вбудованої пам’яті скидає лише таблиці, що належать пам’яті, у базі даних агента. Вона не повинна замінювати весь файл SQLite, бо та сама база даних містить сесії, транскрипти, рядки VFS, артефакти та кеші середовища виконання.
- Реєстри контейнерів/браузерів пісочниці з монолітного та сегментованого JSON. Записи середовища виконання тепер використовують спільну базу даних; імпорт застарілого JSON збережено.
- Визначення завдань Cron, стан розкладу та історія запусків тепер використовують спільний SQLite;
doctor імпортує/видаляє застарілі файли
jobs.json,jobs-state.jsonіcron/runs/*.jsonl - Ідентичність/автентифікація пристрою, push, перевірка оновлень, commitments, кеш моделей OpenRouter, індекс установлених Plugin і прив’язки app-server
- Записи сполучення пристрою/вузла та bootstrap тепер використовують типізовані таблиці SQLite
- Підписники сповіщень про сполучення пристроїв і маркери доставлених запитів тепер використовують
спільну SQLite-таблицю стану Plugin замість
device-pair-notify.json. - Записи дзвінків Voice-call тепер використовують спільну SQLite-таблицю стану Plugin у просторі назв
voice-call/callsзамістьcalls.jsonl; CLI Plugin відстежує хвіст і підсумовує історію дзвінків на базі SQLite. - Сесії Gateway QQBot, записи відомих користувачів і кеш цитат ref-index тепер використовують
стан Plugin SQLite у просторах назв
qqbot(gateway-sessions,known-users,ref-index) замістьsession-*.json,known-users.jsonіref-index.jsonl. Ці застарілі файли є кешами й не мігруються. - Налаштування вибору моделі Discord, хеші розгортання команд і прив’язки потоків
тепер використовують стан Plugin SQLite у просторах назв
discord(model-picker-preferences,command-deploy-hashes,thread-bindings) замістьmodel-picker-preferences.json,command-deploy-cache.jsonіthread-bindings.json; міграція doctor/setup Discord імпортує та видаляє застарілі файли. - Курсори наздоганяння BlueBubbles і вхідні маркери dedupe тепер використовують стан Plugin SQLite
у просторах назв
bluebubbles(catchup-cursors,inbound-dedupe) замістьbluebubbles/catchup/*.jsonіbluebubbles/inbound-dedupe/*.json; міграція doctor/setup BlueBubbles імпортує та видаляє застарілі файли. - Зсуви оновлень Telegram, записи кешу стікерів, записи кешу ланцюжків відповідей,
записи кешу надісланих повідомлень, записи кешу назв тем і прив’язки потоків
тепер використовують стан Plugin SQLite у просторах назв
telegram(update-offsets,sticker-cache,message-cache,sent-messages,topic-names,thread-bindings) замістьupdate-offset-*.json,sticker-cache.json,*.telegram-messages.json,*.telegram-sent-messages.json,*.telegram-topic-names.jsonіthread-bindings-*.json; міграція doctor/setup Telegram імпортує та видаляє застарілі файли. - Курсори наздоганяння iMessage, зіставлення коротких id відповідей і рядки dedupe sent-echo
тепер використовують стан Plugin SQLite у просторах назв
imessage(catchup-cursors,reply-cache,sent-echoes) замістьimessage/catchup/*.json,imessage/reply-cache.jsonlіimessage/sent-echoes.jsonl; міграція doctor/setup iMessage імпортує та видаляє застарілі файли. - Розмови Microsoft Teams, опитування, SSO-токени та навчальні дані зворотного зв’язку тепер
використовують простори назв стану Plugin SQLite (
conversations,polls,sso-tokens,feedback-learnings) замістьmsteams-conversations.json,msteams-polls.json,msteams-sso-tokens.jsonі*.learnings.json; міграція doctor/setup Microsoft Teams імпортує та архівує застарілі файли. Очікувані завантаження є короткоживучим кешем SQLite, а старі JSON-файли кешу не мігруються. - Кеш синхронізації Matrix, метадані сховища, прив’язки потоків, вхідні маркери dedupe,
стан cooldown перевірки запуску, облікові дані, ключі відновлення та криптографічні знімки SDK
IndexedDB тепер використовують простори назв стану/blob Plugin SQLite у
matrix(sync-store,storage-meta,thread-bindings,inbound-dedupe,startup-verification,credentials,recovery-key,idb-snapshots) замістьbot-storage.json,storage-meta.json,thread-bindings.json,inbound-dedupe.json,startup-verification.json,credentials.json,recovery-key.jsonіcrypto-idb-snapshot.json; міграція doctor/setup Matrix імпортує та видаляє ці застарілі файли з коренів сховища Matrix у межах облікового запису. - Курсори шини Nostr і стан публікації профілю тепер використовують стан Plugin SQLite у
просторах назв
nostr(bus-state,profile-state) замістьbus-state-*.jsonіprofile-state-*.json; міграція doctor/setup Nostr імпортує та видаляє застарілі файли. - Перемикачі сесій Active Memory тепер використовують стан Plugin SQLite у
active-memory/session-togglesзамістьsession-toggles.json. - Черги пропозицій Skill Workshop і лічильники рев’ю тепер використовують стан Plugin SQLite
у
skill-workshop/proposalsіskill-workshop/reviewsзамість файлівskill-workshop/<workspace>.jsonдля кожного workspace. - Черги вихідного доставлення та доставлення сесій тепер спільно використовують глобальну SQLite
таблицю
delivery_queue_entriesз окремими назвами черг (outbound-delivery,session-delivery) замість довговічних файлівdelivery-queue/*.json,delivery-queue/failed/*.jsonіsession-delivery-queue/*.json. Крок doctor legacy-state імпортує очікувані та failed рядки, видаляє застарілі маркери доставлення і видаляє старі JSON-файли після імпорту. Поля гарячої маршрутизації та повторних спроб є типізованими стовпцями; JSON payload зберігається лише для replay/debug. - Оренди процесів ACPX тепер використовують стан Plugin SQLite у
acpx/process-leasesзамістьprocess-leases.json. - Метадані запусків резервного копіювання та міграції
Перемістити це до баз даних агентів:
- Корені сесій агентів і payloads session-entry у сумісній формі. Виконано для
записів середовища виконання: гарячі метадані сесій доступні для запитів у
sessions, тоді як повний payloadSessionEntryу застарілій формі лишається вsession_entries. - Події транскриптів агентів. Виконано для записів середовища виконання.
- Контрольні точки Compaction і знімки транскриптів. Виконано для записів середовища виконання:
копії транскриптів контрольних точок є рядками транскриптів SQLite, а метадані контрольних точок
записуються в
transcript_snapshots. Допоміжні засоби контрольних точок Gateway тепер називають ці значення знімками транскриптів, а не вихідними файлами. - Scratch/workspace простори назв VFS агентів. Виконано для записів VFS середовища виконання.
- Payloads вкладень subagent. Виконано для записів середовища виконання: це seed entries VFS SQLite і ніколи не довговічні файли workspace.
- Артефакти інструментів. Виконано для записів середовища виконання.
- Артефакти запусків. Виконано для записів середовища виконання worker через таблицю
run_artifactsдля кожного агента. - Локальні кеші середовища виконання агента. Виконано для scoped cache записів середовища виконання worker через
таблицю
cache_entriesдля кожного агента. Кеші моделей на рівні Gateway лишаються в глобальній базі даних, якщо вони не стануть agent-specific. - Батьківські stream logs ACP. Виконано для записів середовища виконання.
- Сесії ledger replay ACP. Виконано для записів середовища виконання через
acp_replay_sessionsіacp_replay_events; застарілийacp/event-ledger.jsonлишається лише як вхід doctor. - Метадані сесій ACP. Виконано для записів середовища виконання через
acp_sessions; застарілі блокиentry.acpуsessions.jsonє лише вхідними даними міграції doctor. - Sidecars траєкторій, коли вони не є явними файлами експорту. Виконано для записів середовища виконання:
захоплення траєкторії записує рядки
trajectory_runtime_eventsу базу даних агента і дзеркалить run-scoped артефакти в SQLite. Застарілі sidecars є лише вхідними даними імпорту doctor; export може матеріалізувати свіжі JSONL-виводи support-bundle, але не читає і не мігрує старі sidecars траєкторій/транскриптів під час виконання. Захоплення траєкторії середовища виконання відкриває scope SQLite; helpers шляхів JSONL ізольовані для підтримки export/debug і не реекспортуються з runtime module. Метадані траєкторії embedded-runner записують ідентичність{agentId, sessionId, sessionKey}замість збереження locator транскрипту.
Поки що залишити файловими:
openclaw.json- файли облікових даних провайдера або CLI
- маніфести Plugin/package
- користувацькі workspace і Git-репозиторії, коли вибрано дисковий режим
- журнали, призначені для tailing оператором, якщо конкретну поверхню журналу не переміщено
План міграції
Етап 0: Зафіксувати межу
Зробити межу довговічного стану явною, перш ніж переносити більше рядків:
- Додати таблицю
migration_runsдо глобальної бази даних. Виконано для звітів виконання міграції legacy-state. - Додати єдиний сервіс міграції стану, що належить doctor, для імпорту з файлів у базу даних.
Виконано:
openclaw doctor --fixвикористовує реалізацію міграції legacy-state. - Зробити
planread-only і зробити так, щобapplyстворював резервну копію, імпортував, перевіряв, а потім видаляв або поміщав у карантин старі файли. Виконано: doctor створює перевірену резервну копію перед міграцією, передає шлях резервної копії уmigration_runsі повторно використовує шляхи імпортера/видалення. - Додати статичні заборони, щоб новий runtime code не міг записувати застарілі файли стану, тоді як migration code і tests усе ще можуть seed/read їх. Виконано для поточно мігрованих legacy stores; guard також сканує вкладені tests на заборонені runtime transcript locator contracts.
Етап 1: Завершити глобальну control plane
Тримати спільний координаційний стан у state/openclaw.sqlite:
- Агенти та реєстр баз даних агентів
- Ledgers Task і Task Flow
- Стан Plugin
- Реєстр контейнерів/браузерів пісочниці
- Історія запусків Cron/scheduler
- Pairing, device, push, update-check, TUI, кеші OpenRouter/model та інший невеликий gateway-scoped runtime state
- Метадані резервного копіювання та міграції
- Байти медіавкладень Gateway. Виконано для записів середовища виконання; прямі файлові шляхи
є тимчасовими матеріалізаціями для сумісності з відправниками каналів і staging пісочниці.
Runtime allowlists приймають шляхи матеріалізації SQLite, а не застарілі
state/config media roots. Doctor імпортує застарілі медіафайли в
media_blobsі видаляє вихідні файли після успішного запису рядків. - Сесії, події та payload blobs захоплення debug proxy. Виконано: captures живуть
у shared state DB і відкриваються через bootstrap shared state DB, schema,
WAL і busy-timeout settings. Байти payload gzip-стиснені в
capture_blobs.data; немає runtime sidecar DB override для debug proxy, blob directory або proxy-capture-only generated schema/codegen target. Міграція doctor/startup імпортує відвантажені рядкиdebug-proxy/capture.sqliteі referenced payload blobs, включно з активними legacy DB/blob environment overrides, а потім архівує ці джерела, залишаючи сертифікати CA незмінними.
Цей етап також видаляє дубльовані sidecar openers, permission helpers, WAL setup, filesystem pruning і compatibility writers з цих підсистем.
Етап 2: Запровадити бази даних для кожного агента
Створити одну базу даних на агента й зареєструвати її з глобальної БД:
~/.openclaw/state/openclaw.sqlite~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqliteГлобальний рядок agent_databases зберігає шлях, версію схеми, timestamp
last-seen і базові метадані size/integrity. Runtime code запитує в registry
agent DB замість виведення файлових шляхів напряму.
Agent DB володіє:
sessionsяк канонічний корінь сесій, ізsession_entriesяк таблицею корисного навантаження сумісної форми, прив’язаною до цього кореня, іsession_routesяк унікальним пошуком активногоsession_keyconversationsіsession_conversationsяк нормалізована ідентичність маршрутизації провайдера, прив’язана до сесійtranscript_events- знімки транскриптів і контрольні точки Compaction. Виконано для runtime-записів.
vfs_entriestool_artifactsі артефакти запусків- локальні для агента runtime/cache-рядки. Виконано для кешів у межах worker.
- події батьківського потоку ACP
- runtime-події траєкторії, коли вони не є явними артефактами експорту
Етап 3: Замінити API сховища сесій
Виконано для runtime. Файлоподібна поверхня сховища сесій не є активним runtime-контрактом:
- Runtime більше не викликає
loadSessionStore(storePath)і не трактуєstorePathяк ідентичність сесії. - Операції runtime-рядків:
getSessionEntry,upsertSessionEntry,patchSessionEntry,deleteSessionEntryіlistSessionEntries. - Помічники переписування всього сховища, файлові writer-и, тести черг, pruning псевдонімів і параметри видалення legacy-ключів прибрано з runtime.
- Застарілі експорти сумісності кореневого пакета все ще адаптують канонічні
шляхи
sessions.jsonдо API SQLite-рядків. - Розбір
sessions.jsonлишається тільки в коді doctor-міграції/імпорту та тестах doctor. - Runtime fallback життєвого циклу читає SQLite-заголовки транскриптів, а не перші рядки JSONL.
Продовжуйте видаляти все, що повторно вводить параметри file-lock, словник pruning/truncation-as-file-maintenance, ідентичність store-path або тести, єдине твердження яких — JSON-персистентність.
Етап 4: Перенести транскрипти, потоки ACP, траєкторії та VFS
Зробіть кожен потік даних агента database-native:
- Записи додавання транскриптів проходять через одну SQLite-транзакцію, яка забезпечує
заголовок сесії, перевіряє ідемпотентність повідомлення, вибирає батьківський tail, вставляє
у
transcript_eventsі записує метадані ідентичності, доступні для запитів, уtranscript_event_identities. Виконано для прямих додавань повідомлень транскриптів і звичайних persisted-додаваньTranscriptSessionManager; явні branch-операції зберігають свій явний вибір батька й усе ще записують SQLite-рядки без виведення будь-якого файлового locator. - Журнали батьківського потоку ACP стають рядками, а не файлами
.acp-stream.jsonl. Виконано. - Налаштування ACP spawn більше не зберігає JSONL-шляхи транскриптів. Виконано.
- Runtime-захоплення траєкторії напряму записує рядки подій/артефакти. Явна команда support/export усе ще може створювати JSONL-артефакти support-bundle як формат експорту, але експорт сесії не відтворює session JSONL. Виконано.
- Дискові workspaces лишаються на диску, коли налаштовано disk mode.
- VFS scratch і експериментальний режим workspace лише для VFS використовують DB агента.
Міграція один раз імпортує старі JSONL-файли, записує counts/hashes у
migration_runs і видаляє імпортовані файли після перевірок цілісності.
Етап 5: Backup, Restore, Vacuum і Verify
Backup лишається одним архівним файлом:
- Зробіть checkpoint кожної глобальної та агентської бази даних.
- Створіть snapshot кожної DB за допомогою SQLite backup semantics або
VACUUM INTO. - Заархівуйте компактні DB snapshots, config, зовнішні credentials і запитані workspace exports.
- Не включайте сирі live-файли
*.sqlite-walі*.sqlite-shm. - Перевірте, відкривши кожен DB snapshot і виконавши
PRAGMA integrity_check.openclaw backup createвиконує цю перевірку архіву за замовчуванням;--no-verifyпропускає лише post-write archive pass, а не перевірку цілісності створення snapshot. - Restore копіює snapshots назад у їхні цільові шляхи. Ця branch скидає
невипущений SQLite layout до
user_version = 1; майбутні випущені зміни schema можуть додати явні міграції, коли вони знадобляться.
Етап 6: Worker Runtime
Тримайте worker mode експериментальним, поки впроваджується поділ баз даних:
- Workers отримують agent id, run id, filesystem mode і DB registry identity.
- Кожен worker відкриває власне SQLite-з’єднання.
- Parent зберігає повноваження channel delivery, approvals, config і cancellation.
- Почніть з одного worker на active run; додавайте pooling лише після того, як lifecycle і DB connection ownership стануть стабільними.
Етап 7: Видалити старий світ
Виконано для runtime-керування сесіями. Старий світ дозволено лише як явний doctor input або support/export output:
- Жодних runtime-записів
sessions.json, transcript JSONL, sandbox registry JSON, task sidecar SQLite або plugin-state sidecar SQLite. - Жодного JSON/session file pruning, file transcript truncation, session file locks або lock-shaped session tests.
- Жодних runtime compatibility exports, мета яких — підтримувати старі session files актуальними.
- Явні support exports лишаються user-requested archive/materialization formats і не повинні повертати назви файлів у runtime identity.
Backup і Restore
Backups мають бути одним архівним файлом, але захоплення бази даних має бути SQLite-native:
- Зупиніть довготривалу write activity або увійдіть у короткий backup barrier.
- Для кожної глобальної та агентської бази даних виконайте checkpoint.
- Створіть snapshot кожної бази даних за допомогою SQLite backup semantics або
VACUUM INTOу тимчасовий backup directory. - Заархівуйте compacted database snapshots, config file, credentials directory, selected workspaces і manifest.
- Перевірте архів, відкривши кожен включений SQLite snapshot і виконавши
PRAGMA integrity_check.openclaw backup createробить це за замовчуванням;--no-verifyпризначено лише для навмисного пропуску post-write archive pass.
Не покладайтеся на сирі live-копії *.sqlite, *.sqlite-wal і *.sqlite-shm як
основний формат backup. Manifest архіву має записувати database role,
agent id, schema version, source path, snapshot path, byte size і integrity
status.
Restore має відновлювати global database і agent database files зі snapshot-ів архіву. Оскільки SQLite layout ще не випущено, цей refactor зберігає лише version-1 schema плюс doctor file-to-database import. Команда restore спершу перевіряє архів, потім замінює кожен manifest asset із перевіреного extracted payload.
План runtime-refactor
-
Додати API database registry.
- Resolve global DB і per-agent DB paths.
- Тримайте невипущені schemas на
user_version = 1; не додавайте код schema migration runner, доки він не знадобиться випущеній schema. - Додайте close/checkpoint/integrity helpers, які використовують tests, backup і doctor.
-
Collapse sidecar SQLite stores.
- Перенесіть plugin state tables у global database. Виконано для runtime writes; невипущений legacy sidecar importer видалено.
- Перенесіть task registry tables у global database. Виконано для runtime writes; невипущений legacy sidecar importer видалено.
- Перенесіть Task Flow tables у global database. Виконано для runtime writes; невипущений legacy sidecar importer видалено.
- Перенесіть builtin memory-search tables у кожну agent database. Виконано; явний
custom
memorySearch.store.pathтепер видаляється doctor config migration. Full reindex виконується in place лише проти memory tables; старий whole-file swap path і sidecar index swap helper видалено. - Видаліть duplicate database openers, WAL setup, permission helpers і close paths із цих subsystems.
-
Перенести agent-owned tables у per-agent databases.
- Створюйте agent DB on demand через global database registry. Виконано.
- Перенесіть runtime session entries, transcript events, VFS rows і tool artifacts до agent DBs. Виконано.
- Не мігруйте branch-local shared-DB session entries, transcript events, VFS rows або tool artifacts; цей layout ніколи не випускався. Залиште лише legacy file-to-database import у doctor.
-
Замінити API session store.
- Видалити
storePathяк runtime identity. Виконано для runtime і захищеноcheck:database-first-legacy-stores: session metadata, route updates, command persistence, CLI session cleanup, Feishu reasoning previews, transcript-state persistence, subagent depth, auth profile session overrides, parent-fork logic і QA-lab inspection тепер resolve базу даних із канонічних agent/session keys. Gateway/TUI/UI/macOS session-list responses тепер exposedatabasePathзамість legacypath; macOS debug surfaces показують per-agent database як read-only state замість записуsession.storeconfig./status, chat-driven trajectory export і CLI dependency proxies більше не propagate legacy store paths; transcript usage fallback reads SQLite за agent/session identity. Runtime і bridge tests більше не exposestorePath; doctor/migration inputs володіють цією legacy field name. Gateway combined-session loading більше не має спеціальної runtime branch для non-templatedsession.storevalues; він aggregates per-agent SQLite rows. Legacy session-lock doctor lane і його.jsonl.lockcleanup helper було видалено; SQLite тепер є session concurrency boundary. Hot runtime call sites використовують row-oriented helper names, такі якresolveSessionRowEntry; старий compatibility aliasresolveSessionStoreEntryвидалено з runtime і plugin SDK exports.
- Видалити
- Використовуйте row operations
{ agentId, sessionKey }. Виконано:getSessionEntry,upsertSessionEntry,deleteSessionEntry,patchSessionEntryіlistSessionEntries— це SQLite-first APIs, які не вимагають session store path. Status summary, local agent status, health і команда listingopenclaw sessionsтепер читають per-agent rows напряму та відображають per-agent SQLite database paths замість шляхівsessions.json. - Замініть whole-store delete/insert на
upsertSessionEntry,deleteSessionEntry,listSessionEntriesі SQL cleanup queries. Виконано для runtime: hot paths тепер використовують row APIs і conflict-retried row patches; remaining whole-store import/replace helpers обмежені migration import code і SQLite backend tests.- Видаліть
store-writer.tsі writer-queue tests. Виконано. - Видаліть runtime legacy-key pruning і alias-delete parameters із session row upserts/patches. Виконано.
- Видаліть
- Видалити runtime JSON registry behavior.
- Зробіть sandbox registry reads і writes SQLite-only. Виконано.
- Імпортуйте monolithic і sharded JSON лише з migration step. Виконано.
- Видаліть sharded registry locks і JSON writes. Виконано.
- Тримайте одну typed registry table замість зберігання registry rows як generic opaque JSON, якщо shape лишається hot-path operational state. Виконано.
-
Видалити file-lock-shaped session mutation.
- Виконано для runtime lock creation і runtime lock APIs.
- Standalone legacy
.jsonl.lockdoctor cleanup lane видалено. session.writeLockє doctor-migrated legacy config, а не typed runtime setting.- State integrity більше не має окремого orphan transcript-file pruning path; doctor migration imports/removes legacy JSONL sources в одному місці.
- Gateway singleton coordination використовує typed SQLite
state_leasesrows підgateway_locksі більше не expose file-lock directory seam. - Generic plugin SDK dedupe persistence більше не використовує file locks або JSON files; він writes shared SQLite plugin-state rows. Виконано.
- QMD embed coordination використовує SQLite state lease замість
qmd/embed.lock. Виконано.
-
Зробити workers database-aware.
- Workers відкривають власні SQLite-з’єднання.
- Parent володіє delivery, channel callbacks і config.
- Worker отримує agent id, run id, filesystem mode і DB registry identity, а не live handles.
vfs-onlyлишається експериментальним і використовує agent database як storage root.- Спершу тримайте один worker на active run. Pooling може зачекати, доки DB connection lifetime і cancellation behavior не стануть передбачуваними.
-
Інтеграція резервного копіювання.
- Навчити резервне копіювання створювати знімки глобальних і агентських баз даних через SQLite backup або
VACUUM INTO. Виконано для виявлених файлів*.sqliteв активі стану. - Додати перевірку резервної копії на цілісність SQLite і версію схеми. Виконано для створення резервної копії та стандартних перевірок цілісності архіву.
- Записувати метадані запуску резервного копіювання в SQLite. Виконано через спільну таблицю
backup_runsзі шляхом до архіву, статусом і JSON маніфесту. - Додати відновлення з перевірених архівних знімків. Виконано:
openclaw backup restoreперевіряє перед витягненням, використовує нормалізований маніфест верифікатора, підтримує--dry-runі вимагає--yesперед заміною записаних вихідних шляхів. - Включати експорт VFS/робочого простору лише за запитом; не експортувати внутрішні дані сесії як JSON або JSONL.
- Навчити резервне копіювання створювати знімки глобальних і агентських баз даних через SQLite backup або
-
Видалити застарілі тести й код. Виконано для відомих поверхонь runtime-сесій.
-
Видалити тести, які перевіряють створення runtime
sessions.jsonабо файлів transcript JSONL. Виконано для core session store, chat, gateway transcript events, preview, lifecycle, command session-entry updates, auto-reply reset/trace, і memory-core dreaming fixtures, approval target routing, session transcript repair, security permission repair, trajectory export, і session export. Тести transcript для active-memory тепер перевіряють області SQLite і відсутність створення тимчасових або збережених файлів JSONL. Стару регресію heartbeat transcript-pruning видалено, оскільки runtime більше не обрізає JSONL transcripts. Тести інструмента agent session-list більше не моделюють застарілі шляхиsessions.jsonяк форму відповіді gateway; тести app/UI/macOS використовуютьdatabasePath. Тести використання transcript для/statusтепер напряму засівають рядки transcript SQLite замість запису файлів JSONL. Тести життєвого циклу сесій Gateway тепер напряму використовують helpers засівання transcript SQLite; старої форми fixture одно рядкового session-file більше немає в покритті reset і delete.sessions.deleteбільше не повертає поле файлової епохиarchived: []; видалення повідомляє лише результат мутації рядка. Старої опціїdeleteTranscriptтакож більше немає: видалення сесії прибирає канонічний коріньsessionsі дозволяє SQLite каскадно видалити належні сесії рядки transcript, snapshot і trajectory, тож жоден викликач не може залишити осиротілі transcripts або забути гілку очищення. Тести захоплення trajectory у context-engine тепер читають рядкиtrajectory_runtime_eventsз ізольованої агентської бази даних замість читанняsession.trajectory.jsonl. Seed-скрипти Docker MCP channel тепер напряму засівають рядки SQLite. Прямі записиsessions.jsonобмежені fixtures для doctor. Tool Search Gateway E2E читає докази tool-call з рядків transcript SQLite замість сканування файлівagents/<agentId>/sessions/*.jsonl. Host events memory-core і scratch-рядки session-corpus тепер живуть у спільному SQLite plugin-state;events.jsonlіsession-corpus/*.txtє лише застарілими вхідними даними міграції doctor. Активні рядки використовують віртуальні шляхиmemory/session-ingestion/, а не.dreams/session-corpus. Старий модуль repair для memory-core dreaming і його CLI/Gateway тести видалено, оскільки runtime більше не володіє file archive repair для цього корпусу. Тести memory-core bridge/public-artifact більше не показують.dreams/events.jsonl; вони використовують віртуальну назву JSON-артефакту на базі SQLite. Документація тестування Public SDK/Codex тепер говорить про стан сесій SQLite замість session files, а приклад channel-turn більше не відкриває аргументstorePath. Стан синхронізації Matrix тепер напряму використовує сховище SQLite plugin-state. Активні контракти client/runtime передають корінь сховища облікового запису, а не шляхbot-storage.json, і doctor імпортує застарілийbot-storage.jsonу SQLite перед видаленням джерела. Сценарії QA Matrix restart/destructive тепер напряму змінюють рядок синхронізації SQLite замість створення або видалення фальшивих файлівbot-storage.json, а підкладка E2EE передає корінь sync-store замість фальшивого шляхуsync-store.json. Вибір storage-root для Matrix більше не оцінює корені за застарілими sync/thread JSON файлами; він використовує довговічні метадані кореня плюс реальний crypto state. Набір тестів runtime SQLite session backend більше не фабрикуєsessions.json; застарілі source fixtures тепер живуть у тестах doctor, які їх імпортують. Тести сесій Gateway більше не відкривають helpercreateSessionStoreDirабо невикористане налаштування тимчасового session-store path; fixture dirs явні, а пряме налаштування рядків використовує SQLite session-row naming. Покриття parser для doctor-only JSON5 session-store перенесено з infra tests у doctor migration tests, тож runtime test suites більше не володіють застарілим parsing session-file. Runtime-тести Microsoft Teams SSO/pending-upload більше не несуть JSON sidecar fixtures або parsers; парсинг застарілих SSO token живе лише в модулі міграції Plugin. Тести Telegram більше не засівають фальшиві шляхи сховища/tmp/*.json; вони напряму скидають message cache на базі SQLite. Generic OpenClaw test-state helper більше не відкриває застарілий writerauth-profiles.json; тести міграції doctor auth володіють цим fixture локально. Runtime-тести для TUI last-session pointers, exec approvals, active-memory toggles, Matrix dedupe/startup verification, Memory Wiki source sync, current-conversation bindings, onboarding auth, і Hermes secret imports більше не створюють старі sidecar files і не перевіряють, що старі filenames відсутні. Вони доводять поведінку через рядки SQLite і публічні store APIs; тести doctor/migration є єдиним місцем, де мають бути застарілі source filenames. Runtime-тести для device/node pairing, channel allowFrom, restart intents, restart handoff, session delivery queue entries, config health, iMessage caches, cron jobs, PI transcript headers, subagent registries, і managed image attachments також більше не створюють виведені з ужитку JSON/JSONL files лише для доказу, що їх ігнорують або що вони відсутні. PI overflow recovery більше не має fallback SessionManager rewrite/truncation: tool-result truncation і context-engine transcript rewrites змінюють рядки transcript SQLite, потім оновлюють активний prompt state з бази даних. Збережені додавання повідомлень SessionManager делегують atomic SQLite transcript append helper для parent selection і idempotency. Звичайні metadata/custom entry appends також вибирають поточного parent всередині SQLite, тож застарілі manager instances не відроджують pre-SQLite parent-chain races. Synthetic PI tail cleanup для mid-turn prechecks іsessions_yieldтепер напряму обрізає стан transcript SQLite; старий SessionManager tail-removal bridge і його тести видалені. Захоплення checkpoint для Compaction також робить знімки лише з SQLite; викликачі більше не передають живий SessionManager як альтернативне джерело transcript. -
Зберегти тести, які засівають застарілі файли лише для міграції.
-
Доказ JSON-file замінено доказом SQL row для активних runtime surfaces.
-
Додати статичні заборони на runtime-записи до застарілих JSON-шляхів сесій/cache. Виконано для repo guard.
- Зробити звіт міграції придатним для аудиту.
- Записувати запуски міграції в SQLite з часовими мітками started/finished, source
paths, source hashes, counts, warnings і backup path.
Виконано: виконання legacy-state migration тепер зберігають звіт
migration_runsз інвентарем source path/table, SHA-256 source file, sizes, record counts, warnings і backup path. Виконано: виконання legacy-state migration також зберігають рядкиmigration_sourcesдля аудиту на рівні джерел і майбутніх рішень skip/backfill. - Зробити apply ідемпотентним. Повторний запуск після часткового імпорту має або пропускати вже імпортоване джерело, або зливати за стабільним ключем. Виконано: session indexes, transcripts, delivery queues, plugin state, task ledgers і agent-owned global SQLite rows імпортуються через стабільні ключі або семантику upsert/replace, тож повторні запуски зливають без дублювання довговічних рядків.
- Невдалі імпорти мають залишати оригінальний source file на місці.
Виконано: невдалі імпорти transcript тепер залишають оригінальне JSONL джерело за
його виявленим шляхом, а
migration_sourcesзаписує джерело якwarningзremoved_source=0для наступного запуску doctor.
- Записувати запуски міграції в SQLite з часовими мітками started/finished, source
paths, source hashes, counts, warnings і backup path.
Виконано: виконання legacy-state migration тепер зберігають звіт
Правила продуктивності
- Одне з'єднання на thread/process — нормально; не діліться handles між workers.
- Використовуйте WAL,
foreign_keys=ON, 30s busy timeout і короткі write transactionsBEGIN IMMEDIATE. - Тримайте helpers write transaction синхронними, доки/якщо async transaction API не додасть явну семантику mutex/backpressure.
- Тримайте parent delivery writes малими й транзакційними.
- Уникайте переписування всього сховища; використовуйте row-level upsert/delete.
- Додайте indexes для list-by-agent, list-by-session, updated-at, run id і expiration paths перед перенесенням hot code.
- Зберігайте великі artifacts, media і vectors як BLOBs або chunked BLOB rows, а не base64 чи numeric-array JSON.
- Тримайте opaque plugin-state entries малими й scoped.
- Додайте SQL cleanup для TTL/expiration замість filesystem pruning. Виконано для database-owned runtime stores: media, plugin state, plugin blobs, persistent dedupe і agent cache — усі завершуються через SQLite rows. Решта filesystem cleanup обмежена тимчасовими materializations або явними removal commands.
Статичні заборони
Додати repo check, який провалює нові runtime writes до застарілих state paths:
sessions.json*.trajectory.jsonl, окрім матеріалізованих виходів support-bundle.acp-stream.jsonlacp/event-ledger.json- файли кешу середовища виконання
cache/*.json agents/<agentId>/agent/auth.jsonagents/<agentId>/agent/models.jsoncredentials/oauth.jsongithub-copilot.token.jsonopenrouter-models.jsonauth-profiles.jsonauth-state.jsonexec-approvals.jsonworkspace-state.json- Matrix
credentials*.jsonіrecovery-key.json cron/runs/*.jsonlcron/jobs.jsonjobs-state.jsondevice-pair-notify.jsondevices/pending.jsondevices/paired.jsondevices/bootstrap.jsonnodes/pending.jsonnodes/paired.jsonidentity/device.jsonidentity/device-auth.jsonpush/web-push-subscriptions.jsonpush/vapid-keys.jsonpush/apns-registrations.jsonprocess-leases.jsongateway-instance-idsession-toggles.json- Memory-core
.dreams/events.jsonl - Memory-core
.dreams/session-corpus/ - Memory-core
.dreams/daily-ingestion.json - Memory-core
.dreams/session-ingestion.json - Memory-core
.dreams/short-term-recall.json - Memory-core
.dreams/phase-signals.json - Memory-core
.dreams/short-term-promotion.lock - Skill Workshop
skill-workshop/<workspace>.json - Skill Workshop
skill-workshop/skill-workshop-review-*.json - Nostr
bus-state-*.json - Nostr
profile-state-*.json calls.jsonlknown-users.jsonref-index.jsonl- QQBot
session-*.json - BlueBubbles
bluebubbles/catchup/*.json - BlueBubbles
bluebubbles/inbound-dedupe/*.json - Telegram
update-offset-*.json - Telegram
sticker-cache.json - Telegram
*.telegram-messages.json - Telegram
*.telegram-sent-messages.json - Telegram
*.telegram-topic-names.json - Telegram
thread-bindings-*.json - iMessage
catchup/*.json - iMessage
reply-cache.jsonl - iMessage
sent-echoes.jsonl - Microsoft Teams
msteams-conversations.json - Microsoft Teams
msteams-polls.json - Microsoft Teams
msteams-sso-tokens.json - Microsoft Teams
*.learnings.json - Matrix
bot-storage.json - Matrix
sync-store.json - Matrix
thread-bindings.json - Matrix
inbound-dedupe.json - Matrix
startup-verification.json - Matrix
storage-meta.json - Matrix
crypto-idb-snapshot.json - Discord
model-picker-preferences.json - Discord
command-deploy-cache.json - сегментовані JSON-файли реєстру пісочниці
- JSON-файли
/tmp-моста реле native hook plugin-state/state.sqlite- спеціальні допоміжні файли середовища виконання
openclaw-state.sqlite tasks/runs.sqlitetasks/flows/registry.sqlitebindings/current-conversations.jsonrestart-sentinel.jsongateway-restart-intent.jsongateway-supervisor-restart-handoff.jsongateway.<hash>.lockqmd/embed.lockcommands.logconfig-health.jsonport-guard.jsonsettings/voicewake.jsonsettings/voicewake-routing.jsonplugin-binding-approvals.jsonplugins/installs.jsonaudit/file-transfer.jsonlaudit/crestodian.jsonlcrestodian/rescue-pending/*.jsonplugins/phone-control/armed.json- Memory Wiki
.openclaw-wiki/log.jsonl - Memory Wiki
.openclaw-wiki/state.json - Memory Wiki
.openclaw-wiki/locks/ - Memory Wiki
.openclaw-wiki/source-sync.json - Memory Wiki
.openclaw-wiki/import-runs/*.json - Memory Wiki
.openclaw-wiki/cache/agent-digest.json - Memory Wiki
.openclaw-wiki/cache/claims.jsonl - ClawHub
.clawhub/lock.json - ClawHub
.clawhub/origin.json - декорація профілю браузера
.openclaw-profile-decorated - відкривачі сеансів із файловим бекендом
SessionManager.open(...) - фасади списку транскриптів
SessionManager.listAll(...)іTranscriptSessionManager.listAll(...) - фасади форку транскриптів
SessionManager.forkFromSession(...)іTranscriptSessionManager.forkFromSession(...) - фасади заміни змінного сеансу
SessionManager.newSession(...)іTranscriptSessionManager.newSession(...) - фасади розгалужених сеансів
SessionManager.createBranchedSession(...)іTranscriptSessionManager.createBranchedSession(...)
Заборона має дозволяти тестам створювати застарілі фікстури, а коду міграції — читати/імпортувати/видаляти застарілі файлові джерела. Невипущені допоміжні SQLite-файли залишаються забороненими й не отримують дозволів на імпорт через doctor.
Критерії завершення
- Записи даних і кешу середовища виконання йдуть у глобальну або агентську базу даних SQLite.
- Середовище виконання більше не записує індекси сеансів, JSONL транскриптів, JSON реєстру пісочниці, допоміжні SQLite-файли завдань або допоміжні SQLite-файли plugin-state. Імпортери невипущених допоміжних SQLite-файлів завдань і plugin-state видалено.
- Імпорт застарілих файлів виконується лише через doctor.
- Резервне копіювання створює один архів із компактними знімками SQLite та доказом цілісності.
- Агентські workers можуть працювати з диском, scratch VFS або експериментальним сховищем лише VFS.
- Файли конфігурації та явні файли облікових даних залишаються єдиними очікуваними постійними керівними файлами не баз даних.
- Перевірки репозиторію запобігають повторному впровадженню застарілих файлових сховищ середовища виконання.