Get started

Рефакторинг состояния с приоритетом базы данных

Рефакторинг состояния с приоритетом базы данных

Решение

Использовать двухуровневую структуру SQLite:

  • Глобальная база данных: ~/.openclaw/state/openclaw.sqlite
  • База данных агента: одна база данных SQLite на каждого агента для рабочей области, принадлежащей агенту, транскрипта, VFS, артефактов и большого состояния runtime на уровне агента
  • Конфигурация остается файловой: openclaw.json остается вне базы данных. Runtime-профили аутентификации переносятся в SQLite; файлы учетных данных внешнего провайдера или CLI остаются управляемыми владельцем вне базы данных OpenClaw.

Глобальная база данных является базой данных control-plane. Она владеет обнаружением агентов, общим состоянием Gateway, сопряжением, состоянием устройств/узлов, журналами задач и flow, состоянием Plugin, runtime-состоянием планировщика, метаданными резервных копий и состоянием миграций.

База данных агента является базой данных data-plane. Она владеет метаданными сессии агента, потоком событий транскрипта, рабочей областью VFS или scratch-пространством имен, артефактами инструментов, артефактами запусков и доступными для поиска/индексации локальными cache-данными агента.

Это дает одно долговечное глобальное представление без принудительного помещения больших рабочих областей агентов, транскриптов и бинарных scratch-данных в общую полосу записи Gateway.

Жесткий контракт

У этой миграции есть одна каноническая runtime-форма:

  • Строки сессий сохраняют только метаданные сессии. Они не должны сохранять transcriptLocator, пути к файлам транскриптов, sibling JSONL-пути, пути блокировок, метаданные pruning или указатели совместимости файловой эпохи.
  • Идентичность транскрипта всегда является SQLite-идентичностью: {agentId, sessionId} плюс необязательные метаданные topic там, где они нужны протоколу.
  • sqlite-transcript://... не является runtime- или протокольной идентичностью. Новый код не должен выводить, сохранять, передавать, парсить или мигрировать локаторы транскриптов. Runtime и тесты вообще не должны содержать псевдолокаторов; документация может упоминать эту строку только чтобы запретить ее.
  • Устаревшие sessions.json, JSONL транскриптов, .jsonl.lock, pruning, truncation и старая логика путей сессий относятся только к пути миграции/импорта doctor.
  • Устаревшие alias конфигурации сессий относятся только к миграции doctor. Runtime не интерпретирует session.idleMinutes, session.resetByType.dm или cross-agent alias основной сессии agent:main:* для другого настроенного агента.
  • Идентичность маршрутизации сессий является типизированным реляционным состоянием. Горячие runtime- и UI-пути должны читать sessions.session_scope, sessions.account_id, sessions.primary_conversation_id, conversations и session_conversations; они не должны парсить session_key или извлекать session_entries.entry_json для идентичности провайдера, кроме как в виде compatibility-shadow, пока старые call site удаляются.
  • Маркеры direct-message на уровне канала, такие как dm и direct, являются словарем маршрутизации, а не локаторами транскриптов или дескрипторами совместимости file-store.
  • Устаревшая конфигурация hook handler относится только к поверхностям предупреждений/миграции doctor. Runtime не должен загружать hooks.internal.handlers; hooks запускаются только через обнаруженные директории hook и метаданные HOOK.md.
  • Запуск runtime, горячие пути ответов, Compaction, reset, восстановление, диагностика, TTS, memory hooks, subagents, маршрутизация команд Plugin, границы протокола и hooks должны передавать {agentId, sessionId} через runtime.
  • Тесты должны seed и assert строки SQLite-транскриптов через {agentId, sessionId}. Тесты, которые доказывают только передачу JSONL-пути, сохранение caller-supplied locator или совместимость transcript-file, должны быть удалены, если они не покрывают импорт doctor, non-session support/debug materialization или форму протокола.
  • runEmbeddedPiAgent(...), подготовленные worker-запуски и внутренняя embedded попытка не должны принимать локаторы транскриптов. Они открывают SQLite transcript manager по {agentId, sessionId} и передают этот manager во внутреннюю PI-совместимую сессию агента, чтобы устаревшие вызывающие стороны не могли заставить runner писать JSON/JSONL-транскрипты.
  • Диагностика runner должна хранить runtime/cache/payload trace-записи в SQLite. Runtime-диагностика не должна раскрывать параметры переопределения JSONL-файлов или общие helpers экспорта JSONL-транскриптов; пользовательские экспорты могут materialize явные артефакты из строк базы данных, не передавая имена файлов обратно в runtime.
  • Сырое stream-логирование использует OPENCLAW_RAW_STREAM=1 плюс SQLite diagnostic rows. Старый контракт pi-mono file logger PI_RAW_STREAM, PI_RAW_STREAM_PATH и raw-openai-completions.jsonl не является частью runtime или тестов OpenClaw.
  • Индексация памяти QMD не должна экспортировать SQLite-транскрипты в markdown-файлы. QMD индексирует только настроенные файлы памяти; поиск по транскриптам сессий остается основанным на SQLite.
  • Подпуть QMD SDK предназначен только для QMD в новом коде. Helpers индексации SQLite-транскриптов сессий живут в memory-core-host-engine-session-transcripts; любой QMD re-export является только совместимостью и не должен использоваться runtime-кодом.
  • Встроенные memory indexes живут в базе данных агента-владельца. Runtime config и resolved runtime contracts не должны раскрывать memorySearch.store.path; doctor удаляет этот устаревший ключ конфигурации, а текущий код передает агентский databasePath внутренне.

Работа по реализации должна продолжать удалять код, пока эти утверждения не станут истинными без исключений вне границ doctor/import/export/debug.

Целевое состояние и прогресс

Жесткая цель

  • Одна глобальная база данных SQLite владеет состоянием control-plane: state/openclaw.sqlite.
  • Одна база данных SQLite на каждого агента владеет состоянием data-plane: agents/<agentId>/agent/openclaw-agent.sqlite.
  • Конфигурация остается файловой. openclaw.json не является частью этого рефакторинга базы данных.
  • Устаревшие файлы являются только входными данными миграции doctor.
  • Runtime никогда не пишет и не читает JSONL сессий или транскриптов как активное состояние.

Целевые состояния

  • not-started: runtime-код файловой эпохи все еще пишет активное состояние.
  • migrating: код doctor/import может переносить файловые данные в SQLite.
  • dual-read: временный мост читает и SQLite, и устаревшие файлы. Это состояние запрещено для этого рефакторинга, если оно явно не задокументировано как doctor-only.
  • sqlite-runtime: runtime читает и пишет только SQLite.
  • clean: устаревшие runtime API и тесты удалены, а guard предотвращает регрессии.
  • done: документация, тесты, backup, миграция doctor и changed checks доказывают clean-состояние.

Текущее состояние

  • Сессии: clean для runtime. Строки сессий живут в базе данных на уровне агента, runtime API используют {agentId, sessionId} или {agentId, sessionKey}, а sessions.json является только устаревшим входом doctor.
  • Транскрипты: clean для runtime. События транскриптов, идентичности, snapshots и trajectory runtime events живут в базе данных на уровне агента. Runtime больше не принимает локаторы транскриптов или JSONL-пути транскриптов.
  • PI embedded runner: clean. Embedded PI-запуски, подготовленные workers, Compaction и retry loops используют SQLite session scope и отклоняют устаревшие дескрипторы транскриптов.
  • Cron: clean для runtime. Runtime использует cron_jobs и cron_run_logs; runtime-тесты используют именование SQLite storeKey, а файловые пути Cron остаются только в устаревших тестах миграции doctor.
  • Реестр задач: clean. Runtime-строки Task и Task Flow живут в state/openclaw.sqlite; unshipped sidecar SQLite importers удалены.
  • Состояние Plugin: clean. Строки состояния/blob Plugin живут в общей глобальной базе данных; старые sidecar SQLite helpers для plugin-state защищены guard.
  • Память: sqlite-runtime для встроенной памяти и индексации транскриптов сессий. Таблицы memory index живут в базе данных на уровне агента, состояние памяти Plugin использует общие строки plugin-state, а устаревшие файлы памяти являются входами миграции doctor или содержимым пользовательской рабочей области.
  • Backup: sqlite-runtime. Этапы backup compact SQLite snapshots, опускают live WAL/SHM sidecars, проверяют целостность SQLite и записывают backup-запуски в глобальную базу данных.
  • Миграция doctor: migrating, намеренно. Doctor импортирует устаревшие JSON, JSONL и retired sidecar stores в SQLite, записывает migration runs/sources и удаляет успешно обработанные sources.
  • E2E-скрипты: clean для runtime-покрытия. Docker MCP seeding пишет SQLite rows. Docker-скрипт runtime-context создает устаревший JSONL только внутри seed миграции doctor и явно называет устаревший путь индекса сессий.

Оставшаяся работа

  • [x] Переименовать переменные store в runtime-тестах Cron, убрав storePath, если они не являются устаревшими входами doctor. Файлы: 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] Удалить или переименовать устаревшие test mocks экспорта файловой эпохи. Файл: src/auto-reply/reply/commands-export-test-mocks.ts. Доказательство: rg -n 'resolveSessionFilePath|sessionFile|storePath|transcriptLocator' src/auto-reply/reply.
  • [x] Сделать legacy JSONL seed Docker runtime-context очевидно 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, команд и скриптов. Доказательство: 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 run run_3f1cabf6b25c после временной настройки Node 24/pnpm и явной маршрутизации путей для синхронизированной рабочей области без .git.

Не допускать регрессий

  • Никаких локаторов транскриптов.
  • Никаких активных файлов сессий.
  • Никаких фальшивых JSONL test fixtures, кроме устаревших тестов миграции doctor.
  • Никакого сырого доступа к SQLite там, где ожидается Kysely.
  • Никаких новых устаревших DB migrations. Эта структура не shipped; держать версию схемы на 1, если нет сильной причины.

Предположения чтения кода

Нет последующих продуктовых решений, которые блокируют этот план. Реализация должна продолжаться с этими предположениями:

  • Используйте node:sqlite напрямую и требуйте среду выполнения Node 22+ для этого пути хранения.
  • Оставьте ровно один обычный файл конфигурации. Не переносите конфигурацию, манифесты plugin или рабочие области Git в SQLite в рамках этого рефакторинга.
  • Файлы совместимости времени выполнения не требуются. Устаревшие файлы JSON и JSONL являются только входными данными миграции. Локальные для ветки боковые файлы 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/импорта. Doctor нормализует устаревшие файлы транскриптов JSONL перед вставкой строк SQLite; текущие строки времени выполнения уже записаны в текущей схеме транскриптов. Экспорт траекторий/сессий читает эти строки как есть и не должен выполнять устаревшие миграции во время экспорта.
  • Устаревшие помощники разбора/миграции JSONL-транскриптов предназначены только для doctor. Код формата транскриптов времени выполнения строит только текущий контекст SQLite-транскрипта; doctor владеет обновлениями старых записей JSONL перед вставкой строк.
  • Старый принадлежащий времени выполнения помощник потоковой передачи JSONL-транскриптов был удален. Код импорта doctor владеет явным чтением устаревших файлов; история сессий времени выполнения читает строки SQLite.
  • Привязки app-server Codex используют sessionId OpenClaw как канонический ключ в пространстве имен состояния plugin Codex. sessionKey — это метаданные для маршрутизации/отображения, и он не должен заменять долговечный идентификатор сессии или воскрешать идентичность файла транскрипта.
  • Движки контекста получают текущий контракт времени выполнения напрямую. Реестр не должен оборачивать движки прокладками повторных попыток, которые удаляют sessionKey, transcriptScope или prompt; движки, которые не могут принять текущие database-first параметры, должны явно завершаться ошибкой вместо того, чтобы связываться мостом.
  • Вывод резервной копии должен оставаться одним архивным файлом. Содержимое базы данных должно попадать в этот архив как компактные снимки SQLite, а не как сырые активные боковые файлы WAL.
  • Поиск по транскриптам полезен, но не требуется для первого database-first среза. Спроектируйте схему так, чтобы FTS можно было добавить позже.
  • Выполнение worker должно оставаться экспериментальным за настройками, пока граница базы данных стабилизируется.

Результаты чтения кода

Текущая ветка уже вышла за стадию proof-of-concept. Общая база данных существует, Node node:sqlite подключен через небольшой помощник времени выполнения, а бывшие хранилища теперь записывают в state/openclaw.sqlite или во владеющую базу данных openclaw-agent.sqlite.

Оставшаяся работа — не выбор SQLite; она в том, чтобы держать новую границу чистой и удалить все интерфейсы, похожие на совместимость, которые все еще выглядят как старый файловый мир:

  • Session storePath больше не является идентичностью времени выполнения, формой тестовой фикстуры или полем полезной нагрузки статуса. Тесты времени выполнения и bridge больше не содержат имя контракта storePath; код doctor/миграции владеет этим устаревшим словарем.
  • Записи сессий больше не проходят через старую внутрипроцессную очередь store-writer.ts. Записи патчей SQLite вместо этого используют обнаружение конфликтов и ограниченные повторные попытки.
  • Устаревшее обнаружение путей все еще имеет допустимые сценарии миграции, но код времени выполнения должен перестать рассматривать sessions.json и файлы транскриптов JSONL как возможные цели записи.
  • Таблицы, принадлежащие агенту, живут в поагентных базах данных SQLite. Глобальная БД хранит строки реестра/плоскости управления; идентичность транскрипта — это {agentId, sessionId} в поагентных строках транскриптов. Код времени выполнения не должен сохранять пути к файлам транскриптов или мигрировать локаторы транскриптов.
  • Doctor уже импортирует несколько устаревших файлов. Очистка заключается в том, чтобы сделать это одной явной реализацией миграции, которую вызывает doctor, с долговечным отчетом о миграции.

Дополнительных продуктовых вопросов, блокирующих реализацию, нет.

Текущая форма кода

Ветка уже имеет настоящую общую базу SQLite:

  • Минимальная версия среды выполнения теперь Node 22+: package.json, runtime-guard 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 и runtime-модули схемы генерируются из одноразовых баз данных SQLite, созданных из закоммиченных файлов .sql; runtime-код больше не хранит скопированные вручную строки схем для глобальных, агентских или proxy capture-баз данных.
  • Runtime-хранилища выводят типы выбранных и вставленных строк из этих сгенерированных интерфейсов Kysely DB, а не вручную дублируют формы строк SQLite. Raw SQL остается ограниченным применением схем, pragmas и DDL только для миграций.
  • Схемы SQLite сведены к user_version = 1, потому что этот макет базы данных еще не поставлялся. Runtime-открыватели создают только текущую схему; импорт из файлов в базу данных остается в коде 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_state_entries для версионированных JSON-полезных нагрузок и plugin_blob_entries для байтов, с владением namespace/key, очисткой TTL, резервным копированием и записями миграций плагинов. Состояние оркестрации плагинов, принадлежащее хосту, по-прежнему может иметь типизированные таблицы, когда хост владеет контрактом запросов, например plugin_binding_approvals.
  • Миграции Plugin — это миграции данных в namespace, принадлежащих плагинам, а не миграции схемы хоста. Плагин может мигрировать собственные версионированные записи состояния/blob через provider миграций, а хост записывает статус источника/запуска в обычный журнал миграций. Новые установки плагинов не требуют изменения openclaw-state-schema.sql, если только сам хост не берет на себя владение новым межплагиновым контрактом.
  • src/state/openclaw-agent-db.ts открывает agents/<agentId>/agent/openclaw-agent.sqlite, регистрирует базу данных в глобальной БД и владеет агентскими таблицами сеансов, транскриптов, VFS, артефактов, кэша и индекса памяти. Общее runtime-обнаружение теперь читает сгенерированный типизированный реестр agent_databases, а не реализует этот запрос заново в каждой точке вызова.
  • Глобальные и агентские базы данных записывают строку schema_meta с ролью базы данных, версией схемы, временными метками и id агента для агентских баз данных. Макет по-прежнему остается на user_version = 1, потому что эта схема SQLite еще не поставлялась.
  • Идентичность агентских сеансов теперь имеет каноническую корневую таблицу sessions с ключом session_id, где session_key, session_scope, account_id, primary_conversation_id, временные метки, отображаемые поля, метаданные модели, id harness и связь parent/spawn являются запрашиваемыми столбцами. session_routes — это уникальный активный индекс маршрута от session_key к текущему session_id, поэтому ключ маршрута может перейти к новому долговечному сеансу, не заставляя горячие чтения выбирать между дублирующимися строками sessions.session_key. Старый payload совместимой формы session_entries.entry_json привязан к долговечному корню session_id внешним ключом; он больше не является единственным представлением сеанса на уровне схемы.
  • Агентская идентичность внешних разговоров тоже реляционная: conversations хранит нормализованную идентичность provider/account/conversation, а session_conversations связывает один сеанс OpenClaw с одним или несколькими внешними разговорами. Это покрывает shared-main DM-сеансы, где несколько участников могут намеренно сопоставляться с одним сеансом без искажения session_key. SQLite также обеспечивает уникальность естественной идентичности provider, чтобы один и тот же кортеж channel/account/kind/peer/thread не мог разветвиться на разные id разговоров. Shared-main direct peers связываются с ролью participant, поэтому один сеанс OpenClaw может представлять несколько внешних DM-участников, не понижая более старых участников до расплывчатых связанных строк. sessions.primary_conversation_id по-прежнему указывает на текущую типизированную цель доставки. Закрытые столбцы маршрутизации/статуса обеспечиваются ограничениями SQLite CHECK, а не только TypeScript unions. Runtime-проекция сеанса очищает совместимые тени маршрутизации из session_entries.entry_json перед применением типизированных столбцов session/conversation, поэтому устаревшие JSON-полезные нагрузки не могут воскресить цели доставки. Маршрутизация объявлений subagent также требует типизированный контекст доставки SQLite; она больше не откатывается к совместимым полям маршрута SessionEntry. Явное наследование доставки Gateway chat.send читает типизированный контекст доставки SQLite вместо совместимых полей origin/last*. tools.effective аналогично выводит контекст provider/account/thread из типизированных строк доставки/маршрутизации SQLite, а не из устаревших теней last* в session-entry. Контекст prompt для системных событий восстанавливает поля channel/to/account/thread из типизированных полей доставки вместо теней origin. Общий помощник deliveryContextFromSession и mapper session-to-conversation теперь полностью игнорируют SessionEntry.origin; только типизированные поля доставки и реляционные строки разговоров могут создавать горячую идентичность маршрута. Runtime-нормализация записи сеанса удаляет 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 отслеживает изменения revision. Необязательные побочные индексы FTS/vector называются memory_index_chunks_fts и memory_index_chunks_vec вместо общих таблиц meta, files, chunks, chunks_fts или chunks_vec. Канонические имена сохраняют текущую форму строк path/source и совместимость сериализованных embeddings. Эти таблицы являются производным/search-кэшем, а не каноническим хранилищем транскриптов; их можно удалить и перестроить из файлов рабочей области памяти и настроенных источников. Открытие поставлявшегося индекса памяти с общими именами мигрирует его метаданные, источники, chunks и кэш embeddings в канонические таблицы; производные таблицы FTS/vector перестраиваются под каноническими именами.
  • Состояние восстановления запусков subagent теперь живет в типизированных общих строках subagent_runs с индексированными ключами сеансов child, requester и controller. Старый файл subagents/runs.json является только входом миграции doctor.
  • Текущие привязки разговоров теперь живут в типизированных общих строках current_conversation_bindings с ключом по нормализованному id разговора, где целевые столбцы agent/session, kind разговора, статус, срок действия и метаданные хранятся как реляционные столбцы вместо дублированной непрозрачной записи привязки. Долговечный ключ привязки включает нормализованный kind разговора, поэтому ссылки direct/group/channel не могут конфликтовать, а SQLite отклоняет недопустимые значения kind/status привязки. Старый файл bindings/current-conversations.json является только входом миграции doctor.
  • Восстановление очереди доставки теперь накладывает типизированные столбцы очереди для channel, target, account, session, retry, error, platform-send и recovery state поверх JSON воспроизведения. entry_json сохраняет payload воспроизведения, hooks и payload форматирования, но типизированные столбцы являются авторитетными для горячей маршрутизации/состояния очереди.
  • Указатели восстановления последнего сеанса TUI теперь живут в типизированных общих строках tui_last_sessions с ключом по хэшу scope подключения/сеанса TUI. Старый JSON-файл TUI является только входом миграции doctor.
  • Предпочтения TTS по умолчанию теперь живут в общих строках SQLite состояния плагина с ключом под плагином speech-core. Старый файл settings/tts.json является только входом миграции doctor; runtime больше не читает и не пишет JSON-файлы предпочтений TTS, а resolver устаревшего пути живет в модуле миграции doctor.
  • Метаданные secret target теперь говорят о хранилищах, а не притворяются, что каждая credential target является конфигурационным файлом. openclaw.json остается хранилищем конфигурации; цели auth-profile используют типизированные строки SQLite auth_profile_stores, где credentials в форме provider хранятся как JSON-payload.
  • Аудит секретов больше не сканирует устаревшие агентские файлы auth.json. Doctor владеет предупреждением об этом устаревшем файле, его импортом и удалением.
  • Устаревшие помощники путей auth profile теперь живут в legacy-коде doctor. Помощники путей core auth profile раскрывают идентичность и отображаемые расположения SQLite auth-store, а не runtime-пути auth-profiles.json или auth-state.json.
  • Runtime-модули восстановления запусков subagent и кэша возможностей моделей OpenRouter теперь держат SQLite snapshot readers/writers отдельно от doctor-only помощников импорта legacy JSON. Возможности OpenRouter используют типизированные общие строки model_capability_cache под provider_id = "openrouter" вместо одного непрозрачного blob кэша или provider-specific таблицы хоста. taskName запуска subagent хранится в типизированном столбце subagent_runs.task_name; копия payload_json — это данные replay/debug, а не источник горячих полей отображения или поиска.
  • src/agents/filesystem/virtual-agent-fs.sqlite.ts реализует SQLite VFS поверх таблицы агентской базы данных vfs_entries. Чтение каталогов, рекурсивный экспорт, удаления и переименования используют индексированные prefix-диапазоны (namespace, path) вместо сканирования всего namespace или зависимости от сопоставления пути через LIKE.
  • src/agents/runtime-worker.entry.ts создает для каждого запуска SQLite VFS, хранилища артефактов tool, артефактов запуска и scoped cache для workers.
  • Маркеры завершения workspace bootstrap теперь живут в типизированных общих строках workspace_setup_state с ключом по resolved workspace path вместо .openclaw/workspace-state.json; runtime больше не читает и не перезаписывает legacy-маркер workspace, а helper API больше не передают фиктивный путь .openclaw/setup-state только для вывода идентичности хранилища.
  • Exec approvals теперь живут в singleton-строке типизированной общей SQLite exec_approvals_config. Doctor импортирует legacy ~/.openclaw/exec-approvals.json; runtime-записи больше не создают, не перезаписывают и не сообщают этот файл как активное расположение хранилища. macOS companion читает и пишет ту же строку таблицы state/openclaw.sqlite; на диске он держит только Unix prompt socket, потому что это IPC, а не долговечное runtime-состояние.
  • Runtime-модули device identity, device auth и bootstrap теперь держат свои SQLite snapshot readers/writers отдельно от doctor-only помощников импорта legacy JSON. Device identity использует типизированные строки device_identities, а device auth tokens используют типизированные строки device_auth_tokens. Записи device auth согласуют строки по device/role вместо усечения таблицы tokens, и runtime больше не маршрутизирует обновления single-token через старый whole-store adapter. Устаревший Полезные нагрузки JSON версии 1 существуют только как формы импорта/экспорта doctor.
  • Кэш обмена токенов GitHub Copilot использует общую таблицу состояния Plugin в SQLite по пути github-copilot/token-cache/default. Это состояние кэша принадлежит провайдеру, поэтому оно намеренно не добавляет таблицу схемы хоста.
  • Compaction GitHub Copilot больше не записывает боковые файлы рабочей области openclaw-compaction-*.json. Среда вызывает RPC Compaction истории SDK для отслеживаемой сессии SDK, а OpenClaw хранит долговечное состояние сессии/транскрипта в SQLite вместо маркерных файлов совместимости.
  • Общая среда выполнения 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. Среда выполнения больше не читает ключи совместимости SecurePrefs gateway.deviceToken*; они относятся только к логике миграции/doctor.
  • История недавних пакетов уведомлений Android использует типизированные строки android_notification_recent_packages. Среда выполнения больше не мигрирует и не читает старые CSV-ключи SharedPreferences.
  • Создание идентичности устройства завершается закрытым отказом, когда существует устаревший identity/device.json, когда строка идентичности SQLite недействительна или когда хранилище идентичности SQLite невозможно открыть. Doctor сначала импортирует и удаляет этот файл, поэтому запуск среды выполнения не может молча сменить идентичность сопряжения до миграции.
  • Выбор идентичности устройства — это ключ строки SQLite, а не локатор JSON-файла. Тесты и помощники Gateway передают явные ключи идентичности; только миграция doctor и стартовый шлюз с закрытым отказом знают имя удаленного файла identity/device.json.
  • Совместимость сброса сессии теперь находится в миграции конфигурации doctor: session.idleMinutes переносится в session.reset.idleMinutes, session.resetByType.dm переносится в session.resetByType.direct, а политика сброса среды выполнения читает только канонические ключи сброса.
  • Совместимость устаревшей конфигурации теперь находится в src/commands/doctor/. Обычная валидация readConfigFileSnapshot() не импортирует устаревшие детекторы doctor и не аннотирует устаревшие проблемы; runDoctorConfigPreflight() добавляет эти проблемы для исправления/отчетности doctor. Поток конфигурации doctor импортирует src/commands/doctor/legacy-config.ts, а исправление старого OAuth profile-id находится в 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 теперь согласуют подписки/регистрации по первичному ключу вместо очистки их таблиц; здоровье конфигурации делает то же самое по пути конфигурации. Их модули среды выполнения держат читатели/писатели снимков SQLite отдельно от помощников импорта устаревшего JSON, предназначенных только для doctor.
  • Конфигурация Node-хоста теперь использует типизированную singleton-строку в общей базе данных SQLite; doctor импортирует старый файл node.json перед обычным использованием среды выполнения.
  • Сопряжение устройства/узла, сопряжение канала, allowlist каналов и состояние bootstrap теперь используют типизированные строки SQLite вместо целых непрозрачных JSON-блобов. Одобрения привязок Plugin и состояние заданий Cron следуют тому же разделению: модули среды выполнения предоставляют операции на базе SQLite и нейтральные помощники снимков, а записи снимков сопряжения/bootstrap плюс одобрений привязок Plugin согласуют строки по первичному ключу вместо усечения таблиц, тогда как doctor импортирует/удаляет старые JSON-файлы через модули src/commands/doctor/legacy/*.
  • Записи установленных Plugin теперь находятся в SQLite-индексе установленных Plugin. Чтение/запись конфигурации среды выполнения больше не мигрирует и не сохраняет старые данные авторской конфигурации plugins.installs; doctor импортирует эту устаревшую форму конфигурации в SQLite перед обычным использованием среды выполнения.
  • Снимки восстановления учетных данных QQBot теперь находятся в состоянии Plugin SQLite по пути qqbot/credential-backups. Среда выполнения больше не записывает qqbot/data/credential-backup*.json; контракт doctor QQBot импортирует и архивирует эти устаревшие файлы резервных копий из активного каталога состояния.
  • Планирование перезагрузки Gateway сравнивает снимки SQLite-индекса установленных Plugin в внутреннем пространстве различий installedPluginIndex.installRecords.*. Решения о перезагрузке среды выполнения больше не оборачивают эти строки в фиктивные объекты конфигурации plugins.installs.
  • Обновление учетных данных именованной учетной записи Matrix больше не происходит во время чтения среды выполнения. Doctor владеет переименованием старого верхнеуровневого credentials/matrix/credentials.json, когда можно разрешить единственную/default учетную запись Matrix.
  • Основные модули среды выполнения сопряжения и 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. Устаревшие файлы транскриптов являются только входными данными миграции, а шаг миграции владеет импортом и удалением источников.
  • Импорт устаревшего реестра песочниц находится в src/commands/doctor/legacy/sandbox-registry.ts; активные чтения и записи реестра песочниц остаются только SQLite.
  • Устаревшее исправление здоровья/импорта транскриптов сессий находится в src/commands/doctor/legacy/session-transcript-health.ts; командные модули среды выполнения больше не содержат парсинг транскриптов JSONL или код исправления активной ветки.

Основные моменты завершенной консолидации и удаления:

  • Состояние Plugin теперь использует общую базу данных state/openclaw.sqlite. Старый импортер бокового файла plugin-state/state.sqlite, локального для ветки, удален, потому что эта структура SQLite никогда не поставлялась. Вспомогательные средства проб и тестов сообщают общий databasePath вместо раскрытия пути SQLite, специфичного для состояния Plugin.
  • Таблицы среды выполнения задач и потоков задач теперь находятся в общей базе данных state/openclaw.sqlite вместо tasks/runs.sqlite и tasks/flows/registry.sqlite; старые импортеры боковых файлов удалены по той же причине: такая структура никогда не поставлялась.
  • src/config/sessions/store.ts больше не требует storePath для входящих метаданных, обновлений маршрутов или чтения updated-at. Сохранение команд, очистка сессий CLI, глубина subagent, переопределения auth и идентичность сессии транскрипта используют API строк agent/session. Записи применяются как патчи строк 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) остаются как устаревшие shim-обертки для существующих потребителей. Старый вспомогательный метод resolveLegacySessionStorePath удален; построение устаревшего пути sessions.json теперь локально для миграции и тестовых фикстур.
  • src/config/sessions/session-entries.sqlite.ts теперь хранит канонические записи сессий в базе данных каждого агента и поддерживает чтение/upsert/delete-патчи на уровне строк. Runtime upsert/patch/delete больше не сканирует варианты регистра и не удаляет устаревшие alias-ключи; 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, а не 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; предоставленные вызывающим кодом id групп отбрасываются, когда нет типизированной строки сессии, которая их подтверждает.
  • Сопоставление переопределений модели канала теперь использует явные метаданные группы и родительской беседы. Оно больше не декодирует id родительской беседы из parentSessionKey.
  • Наследование сохраненных переопределений модели теперь требует явного ключа родительской сессии из типизированного контекста сессии. Оно больше не выводит родительские переопределения из суффиксов :thread: или :topic: в sessionKey.
  • Старые обертка thread-info сессии и parser thread загруженного Plugin удалены; ни один runtime-код не импортирует config/sessions/thread-info.
  • Вспомогательный метод бесед канала больше не предоставляет мосты разбора полного ключа сессии. Core по-прежнему нормализует принадлежащие провайдеру сырые id бесед через resolveSessionConversation(...), но не реконструирует факты маршрута из sessionKey.
  • Доставка завершений, политика отправки и обслуживание задач больше не выводят тип чата из формы session_key. Старый parser ключа типа чата удален; эти пути требуют типизированных метаданных сессии, типизированного контекста доставки или явного словаря целей доставки.
  • Список/статус сессий, диагностика, привязка аккаунтов approval, фильтрация Heartbeat TUI и сводки использования больше не извлекают маршрутизацию provider/account/thread/display из SessionEntry.origin. Единственные оставшиеся чтения runtime origin относятся к несессионным концепциям или объектам доставки текущего хода.
  • Нативный поиск беседы approval-request теперь читает типизированные строки маршрутизации сессий для каждого агента. Он больше не разбирает идентичность беседы channel/group/thread из sessionKey; отсутствующие типизированные метаданные являются проблемой миграции/исправления.
  • Полезные нагрузки событий Gateway session changed/chat/session больше не дублируют SessionEntry.origin или теневые маршруты last*; клиенты получают типизированные channel, chatType и deliveryContext.
  • Разрешение доставки Heartbeat теперь может получать типизированный SQLite deliveryContext напрямую, а runtime Heartbeat передает строку доставки сессии для каждого агента вместо опоры на совместимые тени session_entries для текущей маршрутизации.
  • Разрешение цели доставки изолированного агента Cron также гидратирует свой текущий маршрут из типизированной строки доставки сессии для каждого агента перед fallback к совместимой полезной нагрузке записи.
  • Разрешение origin объявления subagent теперь протягивает типизированный контекст доставки сессии requester через 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 вместо вывода области channel/direct/group из частей sessionKey. Сессии в области канала наследуют только когда типизированные канал сессии и тип чата совпадают с сохраненным контекстом доставки; сессии shared-main сохраняют свое более строгое правило CLI/no-client-metadata.
  • Пробуждение restart-sentinel и маршрутизация продолжения теперь читают типизированные строки delivery/routing SQLite перед постановкой в очередь пробуждений Heartbeat или маршрутизированных продолжений agent-turn. Они больше не реконструируют контекст доставки из JSON-тени session-entry.
  • Разрешение контекста Gateway tools.effective теперь читает типизированные строки delivery/routing SQLite для входных данных provider, account, target, thread и reply-mode. Оно больше не восстанавливает эти горячие поля маршрутизации из устаревших теней origin session_entries.entry_json.
  • Маршрутизация realtime voice consult теперь разрешает доставку parent/call из типизированных строк сессий SQLite для каждого агента. Она больше не возвращается к совместимым теням SessionEntry.deliveryContext при выборе маршрута сообщения встроенного агента.
  • Ретрансляция ACP spawn Heartbeat и маршрутизация parent-stream теперь читают родительскую доставку из типизированных строк сессий SQLite. Они больше не реконструируют родительский контекст доставки из совместимых теней session-entry.
  • Сохранение маршрута доставки сессии теперь следует типизированным метаданным чата и сохраненным столбцам доставки. Оно больше не извлекает подсказки канала, маркеры direct/main или форму thread из sessionKey; внутренние маршруты webchat наследуют внешнюю цель только когда SQLite уже имеет типизированную/сохраненную идентичность доставки для сессии.
  • Общее извлечение доставки сессии теперь читает только точную типизированную строку доставки сессии SQLite. Оно больше не разбирает суффиксы thread/topic и не откатывается от ключа в форме thread к базовому ключу сессии.
  • Диспетчеризация ответов, восстановление restart sentinel и маршрутизация realtime voice consult теперь используют точные типизированные строки сессий/бесед SQLite для маршрутизации thread. Они больше не восстанавливают id thread или контекст доставки базовой сессии путем разбора ключей сессий в форме thread.
  • Ограничение истории встроенного PI теперь использует типизированную проекцию маршрутизации сессий SQLite (sessions + primary conversations) для provider, типа чата и идентичности peer. Оно больше не разбирает provider, DM, group или форму thread из sessionKey.
  • Вывод доставки инструментов Cron теперь использует только явную доставку или текущий типизированный контекст доставки. Он больше не декодирует цели channel, peer, account или thread из agentSessionKey.
  • Строки runtime-сессий больше не несут старый alias маршрута lastProvider. Вспомогательные средства и тесты используют типизированные поля lastChannel и deliveryContext; миграция doctor — единственное место, которое должно переводить старые alias маршрутов или сохраненные тени origin.
  • События транскрипта, строки VFS и строки артефактов инструментов теперь пишутся в базу данных каждого агента. Непоставлявшаяся глобальная таблица сопоставления файлов транскрипта удалена; doctor вместо этого записывает устаревшие исходные пути в устойчивые строки миграции.
  • Поиск транскриптов runtime больше не сканирует byte offsets JSONL и не проверяет устаревшие файлы транскриптов. Пути Gateway chat/media/history читают строки транскриптов из SQLite; session JSONL теперь является только устаревшим входом doctor, а не состоянием runtime или форматом экспорта.
  • Родительские и ветвящиеся связи транскриптов используют структурированные метаданные parentTranscriptScope: {agentId, sessionId} в заголовках транскриптов SQLite, а не locator-строки в виде path-like agent-db:...transcript_events....
  • Контракт менеджера транскриптов больше не предоставляет неявные сохраненные конструкторы create(cwd) или continueRecent(cwd). Сохраненные менеджеры транскриптов открываются с явной областью {agentId, sessionId}; только in-memory менеджеры остаются без области для тестов и чистых преобразований транскриптов.
  • API хранилища транскриптов runtime разрешают область SQLite, а не пути файловой системы. Старый вспомогательный метод resolve...ForPath и неиспользуемые параметры записи transcriptPath удалены из runtime-вызовов.
  • Разрешение сессий runtime теперь использует {agentId, sessionId} и не должно выводить строки sqlite-transcript://<agent>/<session> для внешних границ. Устаревшие абсолютные пути JSONL являются только входами миграции doctor.
  • Записи прямого моста native hook relay теперь находятся в типизированных общих строках native_hook_relay_bridges, ключом которых является id relay. Runtime больше не пишет JSON-реестр /tmp или непрозрачные generic-записи для этих краткоживущих 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.
  • Перезапись транскрипта и оперативное усечение результатов инструментов теперь читают и сохраняют состояние транскрипта по {agentId, sessionId} и не выводят временные локаторы для payload событий обновления транскрипта.
  • Поверхность helper для состояния транскрипта больше не имеет вариантов readTranscriptState, replaceTranscriptStateEvents или persistTranscriptStateMutation на основе локаторов. Вызывающий код среды выполнения должен использовать API {agentId, sessionId}. Импорт Doctor читает устаревшие файлы по явному пути файла и записывает строки SQLite; он не мигрирует строки локаторов.
  • Контракт диспетчера сеансов среды выполнения больше не предоставляет open(locator), forkFrom(locator) или setTranscriptLocator(...). Постоянные диспетчеры сеансов открываются только по {agentId, sessionId}; helper для списка/форка живут в строко-ориентированных API сеансов и checkpoint вместо фасада диспетчера транскриптов.
  • API чтения транскриптов Gateway сначала принимают область. Они принимают {agentId, sessionId} и не принимают позиционный локатор транскрипта, который мог бы случайно стать идентичностью среды выполнения. Разбор активного локатора транскрипта удален; устаревшие исходные пути читаются только кодом импорта Doctor.
  • События обновления транскрипта также сначала принимают область. emitSessionTranscriptUpdate больше не принимает голую строку локатора, а слушатели маршрутизируют по {agentId, sessionId} без разбора дескриптора.
  • Broadcast session-message в Gateway разрешает ключи сеанса из области агента/сеанса, а не из локатора транскрипта. Старый resolver/cache ключей transcript-locator-to-session удален.
  • SSE session-history в Gateway фильтрует оперативные обновления по области агента/сеанса. Он больше не канонизирует кандидаты локаторов транскрипта, realpath или файловые идентичности транскрипта, чтобы решить, должен ли поток получить обновление.
  • Хуки жизненного цикла сеанса больше не выводят и не предоставляют локаторы транскрипта на session_end. Потребители хуков получают sessionId, sessionKey, id следующих сеансов и контекст агента; файлы транскрипта не являются частью контракта жизненного цикла.
  • Хуки reset также больше не выводят и не предоставляют локаторы транскрипта. Payload before_reset передает восстановленные сообщения SQLite и причину reset, а идентичность сеанса остается в контексте хука.
  • Reset harness агента больше не принимает локатор транскрипта. Dispatch reset ограничен sessionId/sessionKey плюс причина.
  • Типы сеансов расширений агента больше не предоставляют transcriptLocator; расширения должны использовать контекст сеанса и API среды выполнения, а не обращаться к файловой идентичности транскрипта.
  • Хуки Compaction Plugin больше не предоставляют локаторы транскрипта. Контекст хука уже передает идентичность сеанса, а чтение транскриптов должно идти через API, учитывающие область SQLite, вместо файловых дескрипторов.
  • Хуки before_agent_finalize больше не предоставляют transcriptPath, включая payload relay нативных хуков. Хуки финализации используют только контекст сеанса.
  • Ответы reset Gateway больше не синтезируют локатор транскрипта в возвращаемой записи. Reset создает строки транскрипта SQLite, возвращает чистую запись сеанса и оставляет доступ к транскрипту reader, учитывающим область.
  • Результаты встроенного запуска и Compaction больше не показывают локаторы транскрипта для учета сеанса. Автоматическое Compaction обновляет только активный sessionId, счетчики Compaction и метаданные токенов.
  • Результаты встроенных попыток больше не возвращают transcriptLocatorUsed, а результаты compact() context-engine больше не возвращают локаторы транскрипта. Циклы retry среды выполнения принимают только последующий sessionId.
  • Результаты добавления транскрипта delivery-mirror больше не возвращают локаторы транскрипта. Вызывающие получают добавленный messageId; сигналы обновления транскрипта используют область SQLite.
  • Helper форка родительского сеанса возвращают только форкнутый sessionId. Подготовка субагента передает движкам область дочернего агента/сеанса.
  • Параметры CLI runner и повторное заполнение history больше не принимают локаторы транскрипта. Чтение history CLI разрешает область транскрипта SQLite из {agentId, sessionId} и контекста ключа сеанса.
  • Фикстуры тестов CLI и embedded-runner теперь заполняют и читают строки транскрипта SQLite по id сеанса вместо того, чтобы притворяться, что активные сеансы являются файлами *.jsonl, или передавать строку sqlite-transcript://... через параметры среды выполнения.
  • События guard результатов инструментов сеанса отправляются из известной области сеанса даже когда in-memory диспетчер не имеет производного локатора. Его тесты больше не имитируют активные файлы транскрипта /tmp/*.jsonl.
  • Helper BTW и compaction-checkpoint теперь читают и форкают строки транскрипта по области SQLite. Метаданные checkpoint теперь хранят только id сеансов и id leaf/entry; производные локаторы больше не записываются в payload checkpoint.
  • Поиск transcript-key Gateway использует область транскрипта SQLite на границах протокола и больше не выполняет realpath или stat для имен файлов транскриптов.
  • Ротация транскрипта при автоматическом Compaction записывает строки последующего транскрипта напрямую через хранилище транскриптов SQLite. Строки сеансов хранят только идентичность последующего сеанса, а не долговечный путь JSONL или сохраненный локатор.
  • Встроенное Compaction context-engine использует helper ротации транскриптов с именами SQLite. Тесты ротации больше не создают пути JSONL последователей и не моделируют активные сеансы как файлы.
  • Managed outgoing image retention строит ключ кэша transcript-message из статистики транскрипта SQLite вместо вызовов filesystem stat.
  • Блокировки сеансов среды выполнения и отдельная устаревшая lane Doctor для .jsonl.lock удалены.
  • Runtime barrel Microsoft Teams и публичный SDK Plugin больше не реэкспортируют старый helper file-lock; пути постоянного состояния Plugin поддерживаются SQLite.
  • Очистка по возрасту/количеству сеансов и явная очистка сеансов удалены. Doctor владеет устаревшим импортом; устаревшие сеансы сбрасываются или удаляются явно.
  • Проверки целостности Doctor больше не считают устаревший файл JSONL валидным активным транскриптом для строки сеанса SQLite. Состояние активного транскрипта проверяется только через SQLite; устаревшие файлы JSONL сообщаются как входы для миграции/очистки orphan.
  • Doctor больше не считает agents/<agent>/sessions/ обязательным состоянием среды выполнения. Он сканирует этот каталог только когда он уже существует, как вход для устаревшего импорта или очистки orphan.
  • sessions.resolve Gateway, пути patch/reset/compact сеансов, создание субагентов, fast abort, метаданные ACP, изолированные Heartbeat сеансы и patching TUI больше не мигрируют и не очищают устаревшие ключи сеансов как побочный эффект обычной работы среды выполнения.
  • Разрешение сеанса команды CLI теперь возвращает владеющий agentId вместо storePath, и больше не копирует устаревшие строки основного сеанса во время обычного разрешения --to или --session-id. Канонизация устаревшей main-row принадлежит только Doctor.
  • Разрешение глубины субагента среды выполнения больше не читает sessions.json или JSON5 хранилища сеансов. Оно читает SQLite session_entries по id агента, а устаревшие метаданные глубины/сеанса могут попасть только через путь импорта Doctor.
  • Переопределения сеанса профиля auth сохраняются через прямые upsert строк {agentId, sessionKey} вместо ленивой загрузки файлового runtime хранилища сеансов.
  • Verbose gating auto-reply и helper обновления сеанса теперь читают/upsert строки сеансов SQLite по идентичности сеанса и больше не требуют устаревший путь хранилища перед изменением сохраненного состояния строк.
  • Helper метаданных сеанса command-run теперь используют entry-ориентированные имена и пути модулей; старая поверхность helper команд session-store удалена.
  • Начальное заполнение bootstrap header и усиление границы ручного Compaction теперь напрямую изменяют строки транскрипта SQLite. Вызывающий код среды выполнения передает идентичность сеанса, а не доступные для записи пути .jsonl.
  • Replay silent session-rotation копирует недавние ходы пользователя/assistant по {agentId, sessionId} из строк транскрипта SQLite. Он больше не принимает исходные или целевые локаторы транскрипта.
  • Новые строки сеансов среды выполнения больше не хранят локаторы транскрипта. Вызывающие используют {agentId, sessionId} напрямую; команды экспорта/отладки могут выбирать имена выходных файлов, когда материализуют строки.
  • Запуск нового постоянного сеанса транскрипта теперь всегда открывает строки SQLite по области. Диспетчер сеансов больше не переиспользует предыдущий путь транскрипта файловой эпохи или локатор как идентичность нового сеанса.
  • Постоянные сеансы транскрипта используют явный API openTranscriptSessionManagerForSession({agentId, sessionId}). Старые статические фасады SessionManager.create/openForSession/list/forkFromSession удалены, чтобы тесты и код среды выполнения не могли случайно воссоздать обнаружение сеансов файловой эпохи.
  • Runtime Plugin больше не предоставляет api.runtime.agent.session.resolveTranscriptLocatorPath; код Plugin использует helper строк SQLite и значения области.
  • Публичная поверхность SDK session-store-runtime теперь экспортирует только helper строк сеансов и строк транскриптов. Сфокусированные helper схемы/пути/транзакций SQLite живут в sqlite-runtime; сырые helper open/close/reset остаются локальными только для first-party тестов.
  • Устаревшие классификаторы имен файлов trajectory/checkpoint .jsonl теперь живут в модуле устаревших файлов сеансов Doctor. Core validation сеансов больше не импортирует helper файловых артефактов, чтобы решать обычные id сеансов SQLite.
  • Блокирующие запуски субагентов Active Memory используют строки транскрипта SQLite вместо создания временных или постоянных файлов session.jsonl в состоянии Plugin. Старая опция transcriptDir удалена.
  • Одноразовая генерация slug и запуски планировщика Crestodian используют строки транскрипта SQLite вместо создания временных файлов session.jsonl.
  • Запуски helper llm-task и скрытое извлечение commitment также используют строки транскрипта SQLite, поэтому эти model-only вспомогательные сеансы больше не создают временные файлы транскриптов JSON/JSONL.
  • TranscriptSessionManager теперь является только открытой областью транскрипта SQLite. Код среды выполнения открывает его через openTranscriptSessionManagerForSession({agentId, sessionId}); потоки create, branch, continue, list и fork живут в своих SQLite helper строк, а не в статических фасадах диспетчера. Код Doctor/import/debug обрабатывает явные устаревшие исходные файлы вне диспетчера сеансов среды выполнения.
  • Устаревшие фасадные методы SessionManager.newSession() и SessionManager.createBranchedSession() удалены. Новые сеансы и потомки транскриптов создаются их собственным SQLite workflow вместо изменения уже открытого диспетчера в другой постоянный сеанс.
  • Решения о форке родительского транскрипта и создание форка больше не принимают storePath или sessionsDir; они используют область транскрипта SQLite {agentId, sessionId} вместо сохраненных метаданных пути файловой системы.
  • Memory-host больше не экспортирует no-op helper классификации транскриптов каталога сеансов; фильтрация транскриптов теперь выводится из метаданных строк SQLite при построении entry.
  • Тесты экспорта сеансов 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 — единственный код, который импортирует устаревшие имена файлов транскриптов.
  • Заголовки транскриптов времени выполнения начинаются с версии SQLite 1. Обновления старой формы JSONL V1/V2/V3 живут только в импорте doctor и нормализуют импортированные заголовки до текущей версии транскрипта SQLite перед сохранением строк.
  • Защита database-first теперь запрещает SessionManager.listAll и SessionManager.forkFromSession; рабочие процессы перечисления сессий и fork/restore должны оставаться на строковых/области видимости API SQLite.
  • Защита также запрещает устаревшие имена помощников разбора JSONL транскриптов и ремонта active-branch вне кода doctor/import, поэтому время выполнения не может получить второй устаревший путь миграции транскриптов.
  • Встроенные запуски PI отклоняют входящие дескрипторы транскриптов. Они используют идентичность SQLite {agentId, sessionId} перед запуском worker и снова перед тем, как попытка касается состояния транскрипта. Устаревший ввод /tmp/*.jsonl не может выбрать цель записи времени выполнения.
  • Записи трассировки кэша, полезной нагрузки Anthropic, сырого потока и диагностической временной шкалы теперь пишутся в типизированные строки SQLite diagnostic_events. Пакеты стабильности Gateway теперь пишутся в типизированные строки SQLite diagnostic_stability_bundles. Старые пути переопределения JSONL diagnostics.cacheTrace.filePath, OPENCLAW_CACHE_TRACE_FILE, OPENCLAW_ANTHROPIC_PAYLOAD_LOG_FILE и OPENCLAW_DIAGNOSTICS_TIMELINE_PATH удалены, а обычный захват стабильности больше не пишет файлы logs/stability/*.json.
  • Сохранение Cron теперь согласует строки SQLite cron_jobs вместо удаления и повторной вставки всей таблицы заданий при каждом сохранении. Обратные записи целей Plugin обновляют соответствующие строки cron напрямую и сохраняют состояние cron времени выполнения в той же транзакции базы данных состояния.
  • Вызывающие стороны времени выполнения Cron теперь используют стабильный ключ хранилища cron SQLite. Устаревшие пути cron.store являются только входами импорта doctor; производственные пути gateway, обслуживания задач, статуса, журнала запусков и обратной записи цели Telegram используют resolveCronStoreKey и больше не нормализуют ключ как путь. Статус Cron теперь сообщает storeKey, а не старое поле storePath в форме файла.
  • Загрузка и планирование времени выполнения Cron больше не нормализуют устаревшие сохраненные формы заданий, такие как jobId, schedule.cron, числовой atMs, строковые булевы значения или отсутствующий sessionTarget. Импорт устаревшего состояния doctor владеет этими исправлениями до вставки строк в SQLite.
  • ACP spawn больше не разрешает и не сохраняет пути файлов JSONL транскриптов. Настройка spawn и thread-bind сохраняет строку сессии SQLite напрямую и оставляет id сессии как сохраненную идентичность транскрипта.
  • API метаданных сессий ACP теперь читают/перечисляют/upsert строки SQLite по agentId и больше не раскрывают storePath как часть контракта записи сессии ACP.
  • Учет использования сессий и агрегация использования gateway теперь разрешают транскрипты только по {agentId, sessionId}. Кэш стоимости/использования и сводки обнаруженных сессий больше не синтезируют и не возвращают строки локаторов транскриптов.
  • Добавление чата Gateway, сохранение abort-partial, /sessions.send и записи транскриптов webchat media добавляют данные напрямую через область транскрипта SQLite. Помощник внедрения транскрипта gateway больше не принимает параметр transcriptLocator.
  • Обнаружение транскриптов SQLite теперь перечисляет только области транскриптов и статистику: {agentId, sessionId, updatedAt, eventCount}. Мертвый совместимый помощник listSqliteSessionTranscriptLocators и поле locator для каждой строки удалены.
  • Время выполнения ремонта транскриптов теперь предоставляет только repairTranscriptSessionStateIfNeeded({agentId, sessionId}). Старый помощник ремонта на основе локатора удален; код doctor/debug читает явные пути исходных файлов и никогда не мигрирует строки локаторов.
  • Время выполнения ledger replay ACP теперь хранит строки replay для каждой сессии в общей базе данных состояния SQLite вместо acp/event-ledger.json; doctor импортирует и удаляет устаревший файл.
  • Помощники чтения транскриптов Gateway теперь находятся в src/gateway/session-transcript-readers.ts вместо старого имени модуля session-utils.fs. Проверка истории fallback retry названа по содержимому транскрипта SQLite, а не по старой поверхности файлового помощника.
  • Помощники injected-chat и compaction Gateway теперь передают область транскрипта SQLite через внутренние API помощников вместо именования значений путями транскриптов или исходными файлами.
  • Обнаружение продолжения bootstrap теперь проверяет строки транскриптов SQLite через hasCompletedBootstrapTranscriptTurn; оно больше не раскрывает имя помощника в форме файла.
  • Тесты embedded-runner теперь используют идентичность транскрипта SQLite, а открытие нового менеджера транскриптов всегда требует явный sessionId.
  • Помощники индексации памяти теперь используют терминологию транскриптов SQLite от начала до конца: host экспортирует listSessionTranscriptScopesForAgent и sessionTranscriptKeyForScope, целевые очереди синхронизации sessionTranscripts, публичные результаты поиска сессий раскрывают непрозрачные пути transcript:<agent>:<session>, а внутренний ключ источника БД — session:<session> при source_kind='sessions' вместо фиктивного пути файла.
  • Универсальный помощник persistent-dedupe Plugin SDK больше не раскрывает параметры в форме файла. Вызывающие стороны предоставляют ключи области SQLite, а долговечные строки dedupe живут в общем состоянии Plugin.
  • Токены SSO Microsoft Teams перенесены из заблокированных файлов JSON в состояние Plugin SQLite. Doctor импортирует msteams-sso-tokens.json, перестраивает канонические ключи токенов SSO из полезных нагрузок и удаляет исходный файл. Делегированные токены OAuth остаются на существующей приватной границе файлов учетных данных.
  • Состояние кэша синхронизации Matrix перенесено из bot-storage.json в состояние Plugin SQLite. Doctor импортирует устаревшие сырые или обернутые полезные нагрузки синхронизации и удаляет исходный файл. Активные клиенты Matrix и QA Matrix передают корневой каталог sync-store SQLite, а не фиктивный путь sync-store.json или bot-storage.json.
  • Статус устаревшей миграции криптографии Matrix перенесен из legacy-crypto-migration.json в состояние Plugin SQLite. Doctor импортирует старый файл статуса; снимки IndexedDB Matrix SDK перенесены из crypto-idb-snapshot.json в blob-объекты Plugin SQLite. Ключи восстановления Matrix и учетные данные являются строками состояния Plugin SQLite; их старые файлы JSON являются только входами миграции doctor.
  • Журналы активности Memory Wiki теперь используют состояние Plugin SQLite вместо .openclaw-wiki/log.jsonl. Поставщик миграции Memory Wiki импортирует старые журналы JSONL; markdown wiki и содержимое пользовательского vault остаются файловыми как содержимое workspace.
  • Memory Wiki больше не создает .openclaw-wiki/state.json или неиспользуемый каталог .openclaw-wiki/locks. Поставщик миграции удаляет эти выведенные из использования файлы метаданных Plugin, если они все еще есть в старом vault.
  • Записи аудита Crestodian теперь используют основное состояние Plugin SQLite вместо audit/crestodian.jsonl. Doctor импортирует устаревший журнал аудита JSONL и удаляет его после успешного импорта.
  • Записи аудита записи/наблюдения конфигурации теперь используют основное состояние Plugin SQLite вместо logs/config-audit.jsonl. Doctor импортирует устаревший журнал аудита JSONL и удаляет его после успешного импорта.
  • Компаньон macOS больше не пишет локальные для приложения sidecar-файлы logs/config-audit.jsonl или logs/config-health.json при редактировании openclaw.json. Файл конфигурации остается файловым, снимки восстановления остаются рядом с файлом конфигурации, а долговечное состояние аудита/здоровья конфигурации принадлежит хранилищу SQLite Gateway.
  • Ожидающие подтверждения rescue Crestodian теперь используют основное состояние Plugin SQLite вместо crestodian/rescue-pending/*.json. Doctor импортирует устаревшие файлы ожидающих подтверждений и удаляет их после успешного импорта.
  • Временное состояние arm Phone Control теперь использует состояние Plugin SQLite вместо plugins/phone-control/armed.json. Doctor импортирует устаревший файл armed-state в пространство имен phone-control/arm-state и удаляет файл.
  • Doctor больше не исправляет транскрипты JSONL на месте и не создает резервные файлы JSONL. Он импортирует активную ветку в SQLite и удаляет устаревший источник.
  • Поиск транскрипта session-memory hook использует только чтения SQLite по области {agentId, sessionId}. Его помощник больше не принимает и не выводит локаторы транскриптов, чтения устаревших файлов или параметры перезаписи файлов.
  • Привязки разговоров Codex app-server теперь ключуют состояние Plugin SQLite по ключу сессии OpenClaw или явной области {agentId, sessionId}. Они не должны сохранять fallback-привязки по пути транскрипта.
  • Чтения mirrored-history Codex app-server используют только область транскрипта SQLite; они не должны восстанавливать идентичность из путей файлов транскриптов.
  • Пути role-ordering и сброса compaction больше не удаляют старые файлы транскриптов; сброс только ротирует строку сессии SQLite и идентичность транскрипта.
  • Ответы reset и checkpoint Gateway возвращают чистые строки сессий плюс ids сессий. Они больше не синтезируют локаторы транскриптов SQLite для клиентов.
  • Dreaming memory-core больше не очищает строки сессий, проверяя отсутствие файлов JSONL. Очистка subagent проходит через API времени выполнения сессий вместо проверок существования файловой системы. Его тесты ingestion транскриптов наполняют строки SQLite напрямую вместо создания фикстур agents/<id>/sessions или заполнителей локаторов.
  • Индексация транскриптов памяти может раскрывать transcript:<agentId>:<sessionId> как виртуальный путь результата поиска для помощников цитирования/чтения. Долговечный источник индекса является реляционным (source_kind='sessions', source_key='session:<sessionId>', session_id=<sessionId>), поэтому значение не является локатором транскрипта времени выполнения, не является путем файловой системы и никогда не должно передаваться обратно в API времени выполнения сессий.
  • Статус памяти Gateway doctor читает счетчики short-term recall и phase-signal из строк состояния Plugin SQLite вместо memory/.dreams/*.json; вывод CLI и doctor теперь помечает это хранилище как хранилище SQLite, а не путь.
  • Время выполнения memory-core, статус CLI, методы Gateway doctor и фасады Plugin SDK больше не аудируют и не архивируют устаревшие файлы .dreams/session-corpus. Эти файлы являются только входами миграции; doctor импортирует их в SQLite и удаляет источник после проверки. Активные строки доказательств session-ingestion теперь используют виртуальный путь SQLite memory/session-ingestion/<day>.txt; время выполнения никогда не пишет состояние в .dreams/session-corpus и не выводит его оттуда.
  • Публичные артефакты memory-core раскрывают события host SQLite как виртуальный JSON артефакт memory/events/memory-host-events.json; они больше не переиспользуют устаревший исходный путь .dreams/events.jsonl.
  • Реестры контейнеров/браузеров sandbox теперь используют общую таблицу SQLite sandbox_registry_entries с типизированными столбцами сессии, образа, временной метки, backend/config и порта браузера. Doctor импортирует устаревшие монолитные и шардированные JSON-файлы реестра и удаляет успешные источники. Чтения времени выполнения используют типизированные столбцы строк как источник истины; entry_json — только копия для replay/debug.
  • Commitments теперь используют типизированную общую таблицу commitments вместо JSON-blob всего хранилища. Сохранения снимков выполняют upsert по id commitment и удаляют только отсутствующие строки вместо очистки и повторной вставки таблицы. Время выполнения загружает commitments из типизированных столбцов области, окна доставки, статуса, попытки и текста; record_json — только копия для replay/debug. Doctor импортирует устаревший commitments.json и удаляет его после успешного импорта.
  • Определения заданий Cron, состояние расписания и история запусков больше не имеют JSON-писателей или читателей времени выполнения. Время выполнения использует строки cron_jobs с типизированным расписанием, столбцы payload, delivery, failure-alert, session, status и runtime-state, а также типизированные метаданные cron_run_logs для статуса, сводки диагностики, статуса/ошибки доставки, session/run, модели и итогов по токенам. job_json — только копия для воспроизведения/отладки; state_json хранит вложенную диагностику среды выполнения, для которой еще нет полей горячих запросов, тогда как среда выполнения восстанавливает горячие поля состояния из типизированных столбцов. Doctor импортирует устаревшие файлы jobs.json, jobs-state.json и runs/*.jsonl и удаляет импортированные источники. Обратная запись целей Plugin обновляет соответствующие строки cron_jobs вместо загрузки и замены всего хранилища Cron.
  • Запуск Gateway игнорирует устаревшие маркеры notify: true в проекции среды выполнения. Doctor преобразует их в явную доставку SQLite, когда cron.webhook допустим, удаляет неактивные маркеры, когда он не задан, и сохраняет их с предупреждением, когда настроенный Webhook недопустим.
  • Очереди исходящей доставки и доставки сеансов теперь хранят статус очереди, тип записи, ключ сеанса, канал, цель, идентификатор аккаунта, число повторов, последнюю попытку/ошибку, состояние восстановления и маркеры отправки платформы как типизированные столбцы в общей таблице delivery_queue_entries. Восстановление среды выполнения читает эти горячие поля из типизированных столбцов, а мутации повторов/восстановления обновляют эти столбцы напрямую без перезаписи JSON воспроизведения. Полная JSON-полезная нагрузка остается только как блок воспроизведения/отладки для тел сообщений и других холодных данных воспроизведения.
  • Управляемые записи исходящих изображений теперь используют типизированные общие строки managed_outgoing_image_records, при этом байты медиа по-прежнему хранятся в media_blobs. JSON-запись остается только копией для воспроизведения/отладки.
  • Настройки выбора моделей Discord, хэши развертывания команд и привязки веток теперь используют общее SQLite-состояние Plugin. Их устаревшие планы импорта JSON находятся в поверхности настройки/doctor-миграции Plugin Discord, а не в коде миграции ядра.
  • Детекторы устаревшего импорта Plugin используют модули с именами Doctor, такие как doctor-legacy-state.ts или doctor-state-imports.ts; обычные модули среды выполнения каналов не должны импортировать детекторы устаревшего JSON.
  • Курсоры догоняющей синхронизации BlueBubbles и входящие маркеры дедупликации теперь используют общее SQLite-состояние Plugin. Их устаревшие планы импорта JSON находятся в поверхности настройки/doctor-миграции Plugin BlueBubbles, а не в коде миграции ядра.
  • Смещения обновлений Telegram, строки кэша стикеров, строки кэша отправленных сообщений, строки кэша имен тем и привязки веток теперь используют общее SQLite-состояние Plugin. Их устаревшие планы импорта JSON находятся в поверхности настройки/doctor-миграции Plugin Telegram, а не в коде миграции ядра.
  • Курсоры догоняющей синхронизации iMessage, сопоставления коротких идентификаторов ответов и строки дедупликации отправленного эха теперь используют общее SQLite-состояние Plugin. Старые файлы imessage/catchup/*.json, imessage/reply-cache.jsonl и imessage/sent-echoes.jsonl являются только входами Doctor.
  • Строки дедупликации сообщений Feishu теперь используют общее SQLite-состояние Plugin вместо файлов feishu/dedup/*.json. Его устаревший план импорта JSON находится в поверхности настройки/doctor-миграции Plugin Feishu, а не в коде миграции ядра.
  • Беседы, опросы, ожидающие буферы загрузки и извлеченные уроки обратной связи Microsoft Teams теперь используют общие таблицы состояния/blob Plugin в SQLite. Путь ожидающей загрузки использует plugin_blob_entries, поэтому медиабуферы хранятся как SQLite BLOB вместо JSON в base64. Имена помощников среды выполнения теперь используют именование SQLite/state, а не именование файлового хранилища *-fs, и старый shim storePath удален из этих хранилищ. Его устаревший план импорта JSON находится в поверхности настройки/doctor-миграции Plugin Microsoft Teams.
  • Размещенные исходящие медиа Zalo теперь используют общий SQLite plugin_blob_entries вместо временных JSON/bin-сайдкаров openclaw-zalo-outbound-media.
  • HTML и метаданные просмотрщика диффов теперь используют общий SQLite plugin_blob_entries вместо временных файлов meta.json/viewer.html. Отрендеренные PNG/PDF-выходы остаются временными материализациями, потому что доставке каналов все еще нужен путь к файлу.
  • Управляемые документы Canvas теперь используют общий SQLite plugin_blob_entries вместо каталога по умолчанию state/canvas/documents. Хост Canvas обслуживает эти blob напрямую; локальные файлы создаются только для явного операторского контента host.root или временной материализации, когда нижестоящему читателю медиа требуется путь.
  • Решения аудита File Transfer теперь используют общий SQLite plugin_state_entries вместо неограниченного журнала среды выполнения audit/file-transfer.jsonl. Doctor импортирует устаревший файл аудита JSONL в состояние Plugin и удаляет источник после чистого импорта.
  • Аренды процессов ACPX и идентичность экземпляра Gateway теперь используют общее SQLite-состояние Plugin. Doctor импортирует устаревший файл gateway-instance-id в состояние Plugin и удаляет источник.
  • Сгенерированные скрипты-обертки ACPX и изолированный домашний каталог Codex являются временной материализацией под временным корнем OpenClaw, а не долговечным состоянием OpenClaw. Долговечные записи среды выполнения ACPX — это строки аренды SQLite и экземпляра Gateway; старая поверхность конфигурации ACPX stateDir удалена, потому что состояние среды выполнения туда больше не записывается.
  • Медиа-вложения Gateway теперь используют общую SQLite-таблицу media_blobs как каноническое хранилище байтов. Локальные пути, возвращаемые поверхностям совместимости каналов и песочницы, являются временными материализациями строки базы данных, а не долговечным хранилищем медиа. Allowlist медиа среды выполнения больше не включает устаревшие корни $OPENCLAW_STATE_DIR/media или media каталога конфигурации; эти каталоги являются только источниками импорта Doctor.
  • Автодополнение shell больше не записывает файлы кэша $OPENCLAW_STATE_DIR/completions/*. Пути установки, Doctor, обновления и release smoke используют сгенерированный вывод автодополнения или подключение профиля вместо долговечных файлов кэша автодополнения.
  • Промежуточное хранение загрузок Skills в Gateway теперь использует общие строки skill_uploads. Метаданные загрузки, ключи идемпотентности и байты архива находятся в SQLite; установщик получает только временный материализованный путь архива, пока выполняется установка.
  • Встроенные вложения субагентов больше не материализуются в рабочем пространстве .openclaw/attachments/*. Путь spawn подготавливает seed-записи SQLite VFS, встроенные запуски помещают эти записи в scratch-пространство среды выполнения для каждого агента, а инструменты с дисковой поддержкой накладывают этот SQLite scratch для путей вложений. Старые столбцы реестра каталогов вложений запусков субагентов и хуки очистки удалены.
  • Гидратация изображений CLI больше не поддерживает стабильные файлы кэша openclaw-cli-images. Внешние CLI-бэкенды все еще получают пути к файлам, но эти пути являются временными материализациями на один запуск с очисткой.
  • Диагностика cache-trace, диагностика полезной нагрузки Anthropic, диагностика сырого потока модели, события временной шкалы диагностики и пакеты стабильности Gateway теперь записывают строки SQLite вместо файлов logs/*.jsonl или logs/stability/*.json. Флаги переопределения путей среды выполнения и env vars удалены; команды экспорта/отладки могут явно материализовать файлы из строк базы данных.
  • macOS companion больше не имеет скользящего писателя diagnostics.jsonl. Журналы приложения уходят в unified logging, а долговечная диагностика Gateway остается поддержанной SQLite.
  • Список записей macOS port-guardian теперь использует типизированные общие SQLite-строки macos_port_guardian_records вместо JSON-файла Application Support или непрозрачного singleton blob.
  • Singleton-блокировки Gateway теперь используют типизированные общие SQLite-строки state_leases в области gateway_locks вместо файлов блокировок во временном каталоге. Документация по устранению неполадок Fly и OAuth теперь указывает на SQLite-аренду/блокировку обновления auth вместо устаревшей очистки файловых блокировок.
  • Состояние sentinel перезапуска Gateway теперь использует типизированные общие SQLite-строки gateway_restart_sentinel вместо restart-sentinel.json; среда выполнения читает вид sentinel, статус, маршрутизацию, сообщение, продолжение и статистику из типизированных столбцов. payload_json — только копия для воспроизведения/отладки. Код среды выполнения очищает строку SQLite напрямую и больше не несет сантехнику очистки файлов.
  • Намерение перезапуска Gateway и состояние передачи supervisor теперь используют типизированные общие SQLite-строки gateway_restart_intent и gateway_restart_handoff вместо сайдкаров gateway-restart-intent.json и gateway-supervisor-restart-handoff.json.
  • Координация singleton Gateway теперь использует типизированные строки state_leases в gateway_locks вместо записи файлов gateway.<hash>.lock. Строка аренды владеет владельцем блокировки, истечением срока, Heartbeat и отладочной полезной нагрузкой; SQLite владеет атомарной границей acquire/release. Удаленная опция каталога файловых блокировок исчезла; тесты используют идентичность строки SQLite напрямую.
  • Старый неиспользуемый помощник отчета об использовании Cron, который сканировал файлы cron/runs/*.jsonl, удален. Отчеты истории запусков Cron должны читать типизированные SQLite-строки cron_run_logs.
  • Восстановление перезапуска основного сеанса теперь обнаруживает кандидатов-агентов через SQLite-реестр agent_databases вместо сканирования каталогов agents/*/sessions.
  • Восстановление повреждения сеанса Gemini теперь удаляет только строку сеанса SQLite; ему больше не нужен устаревший gate storePath, и он не пытается unlink производный путь JSONL-транскрипта.
  • Обработка переопределения путей теперь считает буквальные значения окружения undefined/null незаданными, предотвращая случайные базы данных undefined/state/*.sqlite в корне репозитория во время тестов или handoff shell.
  • Fingerprint состояния конфигурации теперь используют типизированные общие SQLite-строки config_health_entries вместо logs/config-health.json, оставляя обычный файл конфигурации единственным некреденциальным документом конфигурации. macOS companion хранит только локальное для процесса состояние health и не воссоздает старый JSON-сайдкар.
  • Среда выполнения профилей auth больше не импортирует и не записывает JSON-файлы учетных данных. Каноническое хранилище учетных данных — SQLite; auth-profiles.json, auth.json для каждого агента и общий credentials/oauth.json являются входами doctor-миграции, удаляемыми после импорта.
  • Тесты сохранения/состояния профилей auth теперь проверяют типизированные таблицы auth SQLite напрямую и используют устаревшие имена файлов auth-profile только для входов doctor-миграции.
  • openclaw secrets apply очищает только файл конфигурации, env-файл и SQLite хранилище auth-profile. Он больше не содержит логику совместимости, которая редактирует удаленный auth.json для каждого агента; Doctor отвечает за импорт и удаление этого файла.
  • Планы и применения миграции секретов Hermes импортируют профили API-ключей напрямую в SQLite-хранилище auth-profile. Он больше не записывает и не проверяет auth-profiles.json как промежуточную цель.
  • Пользовательская документация auth теперь описывает state/openclaw.sqlite#table/auth_profile_stores/<agentDir> вместо указаний пользователям проверять или копировать auth-profiles.json; устаревшие имена JSON OAuth/auth остаются задокументированными только как входы импорта Doctor.
  • Помощники путей состояния ядра больше не раскрывают удаленный файл credentials/oauth.json. Устаревшее имя файла локально для пути импорта auth в Doctor.
  • Документация по установке, безопасности, onboarding, model-auth и SecretRef теперь описывает SQLite-строки auth-profile и резервное копирование/миграцию всего состояния вместо JSON-файлов auth-profile для каждого агента.
  • Обнаружение моделей PI теперь передает канонические учетные данные во внутреннее хранилище auth pi-coding-agent в памяти. Оно больше не создает, не очищает и не записывает auth.json для каждого агента во время обнаружения.
  • Настройки триггера и маршрутизации Voice Wake теперь используют типизированные общие SQLite-таблицы вместо settings/voicewake.json, settings/voicewake-routing.json или непрозрачных generic-строк; Doctor импортирует устаревшие JSON-файлы и удаляет их после успешной миграции.
  • Состояние update-check теперь использует типизированную общую строку update_check_state вместо update-check.json или непрозрачного generic blob; Doctor импортирует устаревший JSON-файл и удаляет его после успешной миграции.
  • Состояние config health теперь использует типизированные общие строки config_health_entries вместо logs/config-health.json или непрозрачного generic blob; Doctor импортирует устаревший JSON-файл и удаляет его после успешной миграции.
  • Утверждения привязок бесед Plugin теперь используют типизированные строки plugin_binding_approvals вместо непрозрачного общего SQLite-состояния или plugin-binding-approvals.json; устаревший файл является входными данными для миграции doctor.
  • Универсальные привязки текущего разговора теперь хранят типизированные строки current_conversation_bindings вместо перезаписи bindings/current-conversations.json; doctor импортирует устаревший JSON-файл и удаляет его после успешной миграции.
  • Журналы синхронизации импортированных источников Memory Wiki теперь хранят по одной строке состояния Plugin в SQLite для каждого ключа хранилища/source вместо перезаписи .openclaw-wiki/source-sync.json; поставщик миграции импортирует и удаляет устаревший JSON-журнал.
  • Записи запусков импорта ChatGPT в Memory Wiki теперь хранят по одной строке состояния Plugin в SQLite для каждого идентификатора хранилища/run вместо записи .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, намерение перезапуска и состояние передачи супервизору теперь используют типизированные общие строки SQLite (gateway_restart_sentinel, gateway_restart_intent и gateway_restart_handoff) вместо универсальных непрозрачных blob. Код перезапуска среды выполнения не имеет контракта sentinel/intent/handoff в форме файлов.
  • Кэш синхронизации Matrix, метаданные хранилища, привязки потоков, маркеры дедупликации входящих сообщений, состояние cooldown проверки запуска, криптографические снимки SDK IndexedDB, учетные данные и ключи восстановления теперь используют общие таблицы состояния/blob Plugin в SQLite. Структуры путей среды выполнения больше не предоставляют путь метаданных storage-meta.json; это имя файла является только входными данными устаревшей миграции. Их план импорта устаревшего JSON находится в поверхности настройки/миграции doctor Plugin Matrix.
  • Запуск Matrix больше не сканирует, не сообщает и не завершает устаревшее файловое состояние Matrix. Обнаружение файлов Matrix, создание устаревших криптографических снимков, состояние миграции восстановления ключей комнат, импорт и удаление источников полностью принадлежат doctor.
  • Barrels миграции среды выполнения Matrix были удалены. Помощники обнаружения и изменения устаревшего состояния/криптографии импортируются doctor Matrix напрямую, а не являются частью поверхности 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 и счетчики рецензий теперь используют общее состояние Plugin SQLite вместо хранилищ skill-workshop/<workspace>.json для каждого рабочего пространства. Каждое предложение является отдельной строкой в skill-workshop/proposals, а счетчик рецензий является отдельной строкой в skill-workshop/reviews.
  • Запуски подагентов-рецензентов Skill Workshop теперь используют резолвер стенограммы сеанса среды выполнения вместо создания сайдкар-путей сеанса skill-workshop/<sessionId>.json.
  • Аренды процессов ACPX теперь используют общее состояние Plugin SQLite в acpx/process-leases вместо реестра всего файла process-leases.json. Каждая аренда хранится как отдельная строка, сохраняя очистку устаревших процессов при запуске без пути перезаписи JSON во время выполнения.
  • Скрипты-обертки ACPX и изолированный домашний каталог Codex создаются во временном корне OpenClaw. Они пересоздаются по мере необходимости и не являются входными данными резервного копирования или миграции.
  • Сохранение реестра запусков подагентов использует типизированные общие строки subagent_runs. Старый путь subagents/runs.json теперь является только входными данными миграции doctor, а имена помощников среды выполнения больше не описывают слой состояния как дисковый. Тесты среды выполнения больше не создают недопустимые или пустые фикстуры runs.json для проверки поведения реестра; они напрямую заполняют/читают строки SQLite.
  • Резервное копирование подготавливает каталог состояния перед архивацией, копирует файлы не баз данных, создает снимки баз данных *.sqlite с помощью VACUUM INTO, исключает живые сайдкары WAL/SHM, записывает метаданные снимков в манифест архива и записывает завершенные запуски резервного копирования в SQLite вместе с манифестом архива. openclaw backup create по умолчанию проверяет записанный архив; --no-verify является явным быстрым путем.
  • openclaw backup restore проверяет архив перед извлечением, повторно использует нормализованный манифест верификатора и восстанавливает проверенные ресурсы манифеста в их записанные исходные пути. Для записи требуется --yes, и поддерживается --dry-run для плана восстановления.
  • Старый фильтр volatile-путей резервного копирования удален. Резервному копированию больше не нужен список пропуска live-tar для устаревших JSON/JSONL-файлов сеансов или cron, потому что снимки SQLite подготавливаются перед созданием архива.
  • Обычная настройка и подготовка рабочего пространства onboarding больше не создают каталоги agents/<agentId>/sessions/. Они создают только конфигурацию/рабочее пространство; строки сеансов SQLite и строки стенограмм создаются по требованию в базе данных каждого агента.
  • Восстановление разрешений безопасности теперь нацелено на глобальные и агентские базы данных SQLite плюс сайдкары WAL/SHM вместо sessions.json и JSONL-файлов стенограмм.
  • Имена среды выполнения реестра sandbox теперь напрямую описывают типы реестра SQLite вместо переноса устаревшей терминологии JSON-реестра через активное хранилище.
  • openclaw reset --scope config+creds+sessions удаляет агентские базы данных openclaw-agent.sqlite плюс сайдкары WAL/SHM, а не только устаревшие каталоги sessions/.
  • Агрегированные помощники сеансов Gateway теперь используют имена, ориентированные на записи: loadCombinedSessionEntriesForGateway возвращает { databasePath, entries }. Старое именование combined-store удалено из вызывающих мест среды выполнения.
  • Заполнение канала Docker MCP теперь записывает основную строку сеанса и события стенограммы в агентскую базу данных SQLite вместо создания sessions.json и JSONL-стенограммы.
  • Встроенный hook памяти сеанса теперь разрешает контекст предыдущего сеанса из SQLite по {agentId, sessionId}. Он больше не сканирует, не хранит и не синтезирует пути стенограмм или каталоги workspace/sessions.
  • Встроенный hook журнала команд теперь записывает строки аудита команд в общую таблицу SQLite command_log_entries вместо добавления в logs/commands.log.
  • Allowlist привязки каналов теперь предоставляют только помощники чтения/записи на базе SQLite во время выполнения и в SDK Plugin. Старый резолвер пути *-allowFrom.json и файловый читатель находятся только в устаревшем коде импорта doctor.
  • migration_runs записывает выполнения миграций устаревшего состояния со статусом, временными метками и JSON-отчетами.
  • migration_sources записывает каждый импортированный источник устаревшего файла с хэшем, размером, количеством записей, целевой таблицей, идентификатором запуска, статусом и состоянием удаления источника.
  • backup_runs записывает пути архивов резервных копий, статус и JSON-манифесты.
  • Глобальная схема не хранит неиспользуемую таблицу реестра agents. Обнаружение баз данных агентов является каноническим реестром agent_databases, пока у среды выполнения не появится реальный владелец записей агентов.
  • Сгенерированная конфигурация каталога моделей хранится в типизированных глобальных строках SQLite agent_model_catalogs, ключом которых является каталог агента. Вызывающие места среды выполнения используют ensureOpenClawModelCatalog; API совместимости models.json в коде среды выполнения отсутствует. Реализация пишет в SQLite, а встроенный реестр PI гидратируется из сохраненной полезной нагрузки без создания файла models.json.
  • Markdown-экспорт стенограмм сеансов QMD и конфигурация memory.qmd.sessions были удалены. Нет коллекции стенограмм QMD, runtime-пути qmd/sessions* и файлового моста памяти сеансов.
  • Среда выполнения memory-core импортирует помощники индексации стенограмм SQLite из openclaw/plugin-sdk/memory-core-host-engine-session-transcripts, а не из подпути SDK QMD. Подпуть QMD сохраняет совместимый реэкспорт только для внешних вызывающих мест, пока крупная очистка SDK не сможет его удалить.
  • Собственный index.sqlite QMD теперь является временной материализацией среды выполнения на базе основной таблицы SQLite plugin_blob_entries. Среда выполнения больше не создает долговечный сайдкар ~/.openclaw/agents/<agentId>/qmd.
  • Необязательный Plugin memory-lancedb больше не создает ~/.openclaw/memory/lancedb как неявное хранилище, управляемое OpenClaw. Это внешний backend LanceDB, и он остается отключенным, пока оператор не настроит явный dbPath.
  • check:database-first-legacy-stores отклоняет новый исходный код среды выполнения, который связывает имена устаревших хранилищ с файловыми API в стиле записи. Он также отклоняет исходный код среды выполнения, который повторно вводит удаленные маркеры моста стенограмм transcriptLocator или sqlite-transcript://.... Код миграции, doctor, импорта и явного экспорта вне сеансов остается разрешенным. Более широкие имена устаревших контрактов, такие как sessionFile, storePath и старые фасады файловой эпохи SessionManager, все еще имеют текущих владельцев и требуют отдельной работы над миграционным guard, прежде чем они смогут стать обязательной preflight-проверкой. Guard теперь также покрывает runtime-хранилища cache/*.json, универсальные сайдкары thread-bindings.json, JSON состояния/run-log cron, JSON состояния конфигурации, сайдкары перезапуска и блокировок, настройки Voice Wake, approvals привязки Plugin, JSON индекса установленных Plugin, JSONL аудита File Transfer, журналы активности Memory Wiki, старый текстовый журнал встроенного command-logger и диагностические knobs JSONL raw-stream pi-mono. Он также запрещает старые имена устаревших модулей doctor на корневом уровне, чтобы код совместимости оставался в src/commands/doctor/. Отладочные обработчики Android также используют logcat/вывод в памяти вместо подготовки файлов кэша camera_debug.log или debug_logs.txt.

Целевая форма схемы

Держите схемы явными. Состояние выполнения, принадлежащее хосту, использует типизированные таблицы. Непрозрачное состояние, принадлежащее Plugin, использует plugin_state_entries / plugin_blob_entries; универсальной таблицы хоста kv нет.

Глобальная база данных:

text
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)

База данных агента:

text
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 без изменения канонических таблиц событий:

text
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 должен вызывать один явный шаг миграции, который можно включать в отчет и безопасно запускать повторно:

bash
openclaw doctor --fix

openclaw doctor --fix вызывает реализацию миграции состояния после обычной предварительной проверки конфигурации и создает проверенную резервную копию перед импортом. Запуск среды выполнения и openclaw migrate не должны импортировать устаревшие файлы состояния OpenClaw.

Свойства миграции:

  • Один проход миграции обнаруживает все устаревшие файловые источники и формирует план перед любыми изменениями.
  • Doctor создает проверенный архив резервной копии перед миграцией до импорта устаревших файлов.
  • Импорты идемпотентны и привязаны к пути источника, mtime, размеру, хэшу и целевой таблице.
  • Успешно обработанные исходные файлы удаляются или архивируются после того, как целевая база данных зафиксировала изменения.
  • Неудачные импорты оставляют источник нетронутым и записывают предупреждение в migration_runs.
  • Код среды выполнения читает только SQLite после появления миграции.
  • Путь отката/экспорта обратно в файлы среды выполнения не требуется.

Инвентаризация миграции

Перенесите это в глобальную базу данных:

  • Записи реестра задач среды выполнения теперь используют общую базу данных; не выпускавшийся сопутствующий импортёр tasks/runs.sqlite удалён. Сохранения снимков вставляют или обновляют по id задачи и удаляют только отсутствующие строки задач/доставок.
  • Записи среды выполнения Task Flow теперь используют общую базу данных; не выпускавшийся сопутствующий импортёр tasks/flows/registry.sqlite удалён. Сохранения снимков вставляют или обновляют по id потока и удаляют только отсутствующие строки потоков.
  • Записи состояния Plugin среды выполнения теперь используют общую базу данных; не выпускавшийся сопутствующий импортёр plugin-state/state.sqlite удалён.
  • Встроенный поиск по памяти больше не использует по умолчанию memory/<agentId>.sqlite; его индексные таблицы находятся в базе данных владеющего агента, а явное подключение сопутствующего memorySearch.store.path перенесено в миграцию конфигурации doctor и выведено из эксплуатации.
  • Переиндексация встроенной памяти сбрасывает только таблицы памяти в базе данных агента. Она не должна заменять весь файл SQLite, потому что та же база данных содержит сеансы, транскрипты, строки VFS, артефакты и кэши среды выполнения.
  • Реестры sandbox-контейнеров/браузеров из монолитного и сегментированного JSON. Записи среды выполнения теперь используют общую базу данных; импорт устаревшего JSON сохраняется.
  • Определения заданий Cron, состояние расписания и история запусков теперь используют общий SQLite; doctor импортирует/удаляет устаревшие файлы jobs.json, jobs-state.json и cron/runs/*.jsonl
  • Идентификация/аутентификация устройств, push, проверка обновлений, обязательства, кэш моделей OpenRouter, индекс установленных Plugin и привязки app-server
  • Записи сопряжения и начальной загрузки устройств/узлов теперь используют типизированные таблицы SQLite
  • Подписчики уведомлений device-pair и маркеры доставленных запросов теперь используют общую таблицу состояния Plugin SQLite вместо device-pair-notify.json.
  • Записи звонков voice-call теперь используют общую таблицу состояния Plugin SQLite в пространстве имён 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 и маркеры дедупликации входящих теперь используют состояние 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 ответов и строки дедупликации 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, метаданные хранилища, привязки тредов, маркеры дедупликации входящих, состояние задержки проверки при запуске, учётные данные, ключи восстановления и криптографические снимки 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 для каждого рабочего пространства.
  • Очереди исходящей доставки и доставки сеансов теперь совместно используют глобальную таблицу SQLite delivery_queue_entries под отдельными именами очередей (outbound-delivery, session-delivery) вместо долговечных файлов delivery-queue/*.json, delivery-queue/failed/*.json и session-delivery-queue/*.json. Шаг doctor legacy-state импортирует ожидающие и неудавшиеся строки, удаляет устаревшие маркеры доставленных сообщений и удаляет старые файлы JSON после импорта. Поля горячей маршрутизации и повторов являются типизированными столбцами; полезная нагрузка JSON сохраняется только для повторного воспроизведения/отладки.
  • Аренды процессов ACPX теперь используют состояние Plugin SQLite в acpx/process-leases вместо process-leases.json.
  • Метаданные запусков резервного копирования и миграции

Перенести это в базы данных агентов:

  • Корни сеансов агентов и payload session-entry в форме совместимости. Выполнено для записей среды выполнения: горячие метаданные сеанса доступны для запросов в sessions, а полный payload SessionEntry в устаревшей форме остаётся в session_entries.
  • События транскриптов агентов. Выполнено для записей среды выполнения.
  • Контрольные точки Compaction и снимки транскриптов. Выполнено для записей среды выполнения: копии транскриптов контрольных точек являются строками транскриптов SQLite, а метаданные контрольных точек записываются в transcript_snapshots. Помощники контрольных точек Gateway теперь называют эти значения снимками транскриптов, а не исходными файлами.
  • Scratch/workspace пространства имён VFS агента. Выполнено для записей VFS среды выполнения.
  • Payload вложений субагентов. Выполнено для записей среды выполнения: это seed-записи VFS SQLite, а не долговечные файлы рабочего пространства.
  • Артефакты инструментов. Выполнено для записей среды выполнения.
  • Артефакты запусков. Выполнено для записей среды выполнения worker через таблицу run_artifacts конкретного агента.
  • Локальные кэши среды выполнения агента. Выполнено для записей scoped-кэша среды выполнения worker через таблицу cache_entries конкретного агента. Общие для Gateway кэши моделей остаются в глобальной базе данных, если не станут специфичными для агента.
  • Журналы родительских потоков ACP. Выполнено для записей среды выполнения.
  • Сеансы журнала replay ACP. Выполнено для записей среды выполнения через acp_replay_sessions и acp_replay_events; устаревший acp/event-ledger.json остаётся только как входные данные doctor.
  • Метаданные сеансов ACP. Выполнено для записей среды выполнения через acp_sessions; устаревшие блоки entry.acp в sessions.json являются только входными данными миграции doctor.
  • Сопутствующие файлы траекторий, когда они не являются явными файлами экспорта. Выполнено для записей среды выполнения: захват траектории записывает строки trajectory_runtime_events в базу данных агента и зеркалирует артефакты, ограниченные запуском, в SQLite. Устаревшие сопутствующие файлы являются только входными данными импорта doctor; экспорт может материализовать новые выходные JSONL для support bundle, но не читает и не мигрирует старые сопутствующие файлы траекторий/транскриптов во время выполнения. Захват траектории среды выполнения раскрывает область SQLite; помощники путей JSONL изолированы для поддержки экспорта/отладки и не реэкспортируются из модуля среды выполнения. Метаданные траектории встроенного runner записывают идентичность {agentId, sessionId, sessionKey} вместо сохранения локатора транскрипта.

Пока оставить файловыми:

  • openclaw.json
  • файлы учётных данных provider или CLI
  • манифесты Plugin/пакетов
  • пользовательские рабочие пространства и Git-репозитории, когда выбран дисковый режим
  • журналы, предназначенные для отслеживания оператором, если конкретная поверхность журналирования не перенесена

План миграции

Фаза 0: Зафиксировать границу

Сделать границу долговечного состояния явной перед переносом дополнительных строк:

  • Добавить таблицу migration_runs в глобальную базу данных. Выполнено для отчётов о выполнении миграции legacy-state.
  • Добавить единую, принадлежащую doctor службу миграции состояния для импорта из файлов в базу данных. Выполнено: openclaw doctor --fix использует реализацию миграции legacy-state.
  • Сделать plan доступным только для чтения, а apply должен создавать резервную копию, импортировать, проверять и затем удалять или помещать старые файлы в карантин. Выполнено: doctor создаёт проверенную резервную копию перед миграцией, передаёт путь резервной копии в migration_runs и повторно использует пути импортёра/удаления.
  • Добавить статические запреты, чтобы новый код среды выполнения не мог записывать устаревшие файлы состояния, пока код миграции и тесты всё ещё могут их создавать/читать. Выполнено для текущих мигрированных устаревших хранилищ; проверка также сканирует вложенные тесты на запрещённые контракты локатора транскриптов среды выполнения.

Фаза 1: Завершить глобальную плоскость управления

Держать общее координационное состояние в state/openclaw.sqlite:

  • Агенты и реестр баз данных агентов
  • Реестры задач и Task Flow
  • Состояние Plugin
  • Реестр sandbox-контейнеров/браузеров
  • История запусков Cron/планировщика
  • Сопряжение, устройство, push, проверка обновлений, TUI, кэши OpenRouter/моделей и другое небольшое состояние среды выполнения, ограниченное Gateway
  • Метаданные резервного копирования и миграции
  • Байты медиа-вложений Gateway. Выполнено для записей среды выполнения; прямые файловые пути являются временными материализациями для совместимости с отправителями каналов и staging sandbox. allowlist среды выполнения принимает пути материализации SQLite, а не устаревшие корни media state/config. Doctor импортирует устаревшие медиафайлы в media_blobs и удаляет исходные файлы после успешной записи строк.
  • Сеансы захвата debug proxy, события и blob payload. Выполнено: захваты находятся в общей БД состояния и открываются через bootstrap общей БД состояния, схему, WAL и настройки busy-timeout. Байты payload сжаты gzip в capture_blobs.data; нет переопределения sidecar DB среды выполнения debug proxy, каталога blob или отдельной сгенерированной схемы/цели codegen только для proxy-capture. Миграция doctor/startup импортирует строки выпущенного debug-proxy/capture.sqlite и связанные blob payload, включая активные устаревшие переопределения окружения DB/blob, затем архивирует эти источники, оставляя сертификаты CA нетронутыми.

Эта фаза также удаляет дублирующие открыватели sidecar, помощники разрешений, настройку WAL, очистку файловой системы и писатели совместимости из этих подсистем.

Фаза 2: Ввести базы данных для каждого агента

Создать одну базу данных на агента и зарегистрировать её из глобальной БД:

text
~/.openclaw/state/openclaw.sqlite~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite

Глобальная строка agent_databases хранит путь, версию схемы, отметку времени последнего появления и базовые метаданные размера/целостности. Код среды выполнения запрашивает у реестра БД агента вместо прямого вывода файловых путей.

БД агента владеет:

  • sessions как канонический корень сессий, с session_entries как таблицей полезной нагрузки в форме совместимости, привязанной к этому корню, и session_routes как уникальным поиском активного session_key
  • conversations и session_conversations как нормализованная идентичность маршрутизации провайдера, привязанная к сессиям
  • transcript_events
  • снимки транскриптов и контрольные точки Compaction. Готово для записей среды выполнения.
  • vfs_entries
  • tool_artifacts и артефакты запусков
  • локальные для агента строки среды выполнения/кэша. Готово для кэшей в области worker.
  • события родительского потока ACP
  • события среды выполнения траектории, когда они не являются явными артефактами экспорта

Фаза 3: заменить API хранилища сессий

Готово для среды выполнения. Поверхность хранилища сессий в файловой форме не является активным контрактом среды выполнения:

  • Среда выполнения больше не вызывает loadSessionStore(storePath) и не считает storePath идентичностью сессии.
  • Операции среды выполнения со строками: getSessionEntry, upsertSessionEntry, patchSessionEntry, deleteSessionEntry и listSessionEntries.
  • Помощники перезаписи всего хранилища, файловые писатели, тесты очередей, очистка алиасов и параметры удаления устаревших ключей удалены из среды выполнения.
  • Устаревшие экспорты совместимости корневого пакета по-прежнему адаптируют канонические пути sessions.json к API строк SQLite.
  • Разбор sessions.json остается только в коде миграции/импорта doctor и тестах doctor.
  • Резервное чтение жизненного цикла среды выполнения читает заголовки транскриптов SQLite, а не первые строки JSONL.

Продолжайте удалять все, что повторно вводит параметры файловых блокировок, словарь очистки/усечения как файлового обслуживания, идентичность пути хранилища или тесты, единственная проверка которых — сохранение JSON.

Фаза 4: перенести транскрипты, потоки ACP, траектории и VFS

Сделайте каждый поток данных агента нативным для базы данных:

  • Записи добавления транскрипта проходят через одну транзакцию SQLite, которая обеспечивает заголовок сессии, проверяет идемпотентность сообщений, выбирает родительский хвост, вставляет в transcript_events и записывает запрашиваемые метаданные идентичности в transcript_event_identities. Готово для прямых добавлений сообщений транскрипта и обычных сохраненных добавлений TranscriptSessionManager; явные операции с ветками сохраняют свой явный выбор родителя и все еще записывают строки SQLite без вывода какого-либо файлового локатора.
  • Журналы родительских потоков ACP становятся строками, а не файлами .acp-stream.jsonl. Готово.
  • Настройка порождения ACP больше не сохраняет пути JSONL транскриптов. Готово.
  • Захват траекторий среды выполнения записывает строки событий/артефакты напрямую. Явная команда поддержки/экспорта все еще может создавать артефакты JSONL для пакета поддержки как формат экспорта, но экспорт сессии не пересоздает JSONL сессии. Готово.
  • Дисковые рабочие пространства остаются на диске, когда настроен дисковый режим.
  • Черновые VFS и экспериментальный режим рабочего пространства только VFS используют базу данных агента.

Миграция однократно импортирует старые файлы JSONL, записывает счетчики/хэши в migration_runs и удаляет импортированные файлы после проверок целостности.

Фаза 5: резервное копирование, восстановление, Vacuum и проверка

Резервные копии остаются одним архивным файлом:

  • Создать контрольную точку для каждой глобальной базы данных и базы данных агента.
  • Снять снимок каждой БД с семантикой резервного копирования SQLite или VACUUM INTO.
  • Архивировать компактные снимки БД, конфигурацию, внешние учетные данные и запрошенные экспорты рабочих пространств.
  • Не включать сырые live-файлы *.sqlite-wal и *.sqlite-shm.
  • Проверять, открывая каждый снимок БД и выполняя PRAGMA integrity_check. openclaw backup create выполняет эту проверку архива по умолчанию; --no-verify пропускает только проход проверки архива после записи, а не проверку целостности при создании снимка.
  • Восстановление копирует снимки обратно в их целевые пути. Эта ветка сбрасывает не выпущенную раскладку SQLite до user_version = 1; будущие выпущенные изменения схемы смогут добавить явные миграции, когда они понадобятся.

Фаза 6: среда выполнения Worker

Сохраняйте режим worker экспериментальным, пока внедряется разделение базы данных:

  • Workers получают идентификатор агента, идентификатор запуска, режим файловой системы и идентичность реестра БД.
  • Каждый worker открывает собственное соединение SQLite.
  • Родитель сохраняет полномочия доставки в каналы, approvals, конфигурации и отмены.
  • Начните с одного worker на активный запуск; добавляйте пул только после того, как жизненный цикл и владение соединениями БД станут стабильными.

Фаза 7: удалить старый мир

Готово для управления сессиями среды выполнения. Старый мир разрешен только как явный ввод doctor или вывод поддержки/экспорта:

  • Нет записей sessions.json, JSONL транскриптов, JSON реестра песочницы, sidecar SQLite задач или sidecar SQLite состояния Plugin в среде выполнения.
  • Нет очистки JSON/файлов сессий, усечения файлов транскриптов, файловых блокировок сессий или тестов сессий в форме блокировок.
  • Нет экспортов совместимости среды выполнения, цель которых — поддерживать старые файлы сессий актуальными.
  • Явные экспорты поддержки остаются запрашиваемыми пользователем форматами архива/материализации и не должны передавать имена файлов обратно в идентичность среды выполнения.

Резервное копирование и восстановление

Резервные копии должны быть одним архивным файлом, но захват базы данных должен быть нативным для SQLite:

  1. Остановите долгие операции записи или войдите в короткий барьер резервного копирования.
  2. Для каждой глобальной базы данных и базы данных агента выполните контрольную точку.
  3. Снимите снимок каждой базы данных с семантикой резервного копирования SQLite или VACUUM INTO во временный каталог резервной копии.
  4. Архивируйте компактные снимки баз данных, файл конфигурации, каталог учетных данных, выбранные рабочие пространства и манифест.
  5. Проверьте архив, открыв каждый включенный снимок SQLite и выполнив PRAGMA integrity_check. openclaw backup create делает это по умолчанию; --no-verify предназначен только для намеренного пропуска прохода проверки архива после записи.

Не полагайтесь на сырые live-копии *.sqlite, *.sqlite-wal и *.sqlite-shm как основной формат резервной копии. Манифест архива должен записывать роль базы данных, идентификатор агента, версию схемы, исходный путь, путь снимка, размер в байтах и статус целостности.

Восстановление должно заново создавать глобальную базу данных и файлы баз данных агентов из снимков архива. Поскольку раскладка SQLite еще не была выпущена, этот рефакторинг сохраняет только схему версии 1 плюс импорт из файлов в базу данных через doctor. Команда восстановления сначала проверяет архив, затем заменяет каждый ресурс манифеста из проверенной извлеченной полезной нагрузки.

План рефакторинга среды выполнения

  1. Добавить API реестра базы данных.

    • Разрешать пути глобальной БД и БД на каждого агента.
    • Сохранять не выпущенные схемы на user_version = 1; не добавлять код запуска миграций схемы, пока выпущенной схеме это не понадобится.
    • Добавить помощники закрытия/контрольной точки/целостности, используемые тестами, резервным копированием и doctor.
  2. Свернуть sidecar-хранилища SQLite.

    • Перенести таблицы состояния Plugin в глобальную базу данных. Готово для записей среды выполнения; не выпущенный устаревший sidecar-импортер удален.
    • Перенести таблицы реестра задач в глобальную базу данных. Готово для записей среды выполнения; не выпущенный устаревший sidecar-импортер удален.
    • Перенести таблицы TaskFlow в глобальную базу данных. Готово для записей среды выполнения; не выпущенный устаревший sidecar-импортер удален.
    • Перенести встроенные таблицы поиска по памяти в базу данных каждого агента. Готово; явный пользовательский memorySearch.store.path теперь удаляется миграцией конфигурации doctor. Полная переиндексация выполняется на месте только по таблицам памяти; старый путь замены всего файла и помощник замены sidecar-индекса удалены.
    • Удалить дублирующиеся открыватели базы данных, настройку WAL, помощники разрешений и пути закрытия из этих подсистем.
  3. Перенести таблицы, принадлежащие агенту, в базы данных на каждого агента.

    • Создавать БД агента по требованию через глобальный реестр базы данных. Готово.
    • Перенести записи сессий среды выполнения, события транскриптов, строки VFS и артефакты инструментов в БД агентов. Готово.
    • Не мигрировать локальные для ветки записи сессий общей БД, события транскриптов, строки VFS или артефакты инструментов; эта раскладка никогда не выпускалась. Сохранять только устаревший импорт из файлов в базу данных в doctor.
  4. Заменить API хранилища сессий.

    • Удалить storePath как идентичность среды выполнения. Готово для среды выполнения и защищено check:database-first-legacy-stores: метаданные сессии, обновления маршрутов, сохранение команд, очистка сессий CLI, превью рассуждений Feishu, сохранение состояния транскрипта, глубина subagent, переопределения сессии профиля auth, логика родительского fork и проверка QA-lab теперь разрешают базу данных из канонических ключей агента/сессии. Ответы списков сессий Gateway/TUI/UI/macOS теперь раскрывают databasePath вместо устаревшего path; поверхности отладки macOS показывают базу данных на каждого агента как состояние только для чтения вместо записи конфигурации session.store. /status, экспорт траекторий через чат и прокси зависимостей CLI больше не распространяют устаревшие пути хранилища; резервное чтение использования транскриптов читает SQLite по идентичности агента/сессии. Тесты среды выполнения и bridge больше не раскрывают storePath; вводы doctor/миграции владеют этим устаревшим именем поля. Загрузка объединенных сессий Gateway больше не имеет специальной ветки среды выполнения для нетемплейтных значений session.store; она агрегирует строки SQLite на каждого агента. Устаревшая ветка doctor для блокировок сессий и ее помощник очистки .jsonl.lock были удалены; теперь SQLite является границей конкурентности сессий. Горячие места вызовов среды выполнения используют имена помощников, ориентированные на строки, такие как resolveSessionRowEntry; старый алиас совместимости resolveSessionStoreEntry удален из среды выполнения и экспортов Plugin SDK.
  • Использовать операции со строками { agentId, sessionKey }. Готово: getSessionEntry, upsertSessionEntry, deleteSessionEntry, patchSessionEntry и listSessionEntries — SQLite-first API, которым не требуется путь хранилища сессий. Сводка статуса, статус локального агента, health и команда списка openclaw sessions теперь читают строки на каждого агента напрямую и отображают пути баз данных SQLite на каждого агента вместо путей sessions.json.
  • Заменить удаление/вставку всего хранилища на upsertSessionEntry, deleteSessionEntry, listSessionEntries и SQL-запросы очистки. Готово для среды выполнения: горячие пути теперь используют API строк и повторяемые при конфликте патчи строк; оставшиеся помощники импорта/замены всего хранилища ограничены кодом импорта миграций и тестами backend SQLite.
    • Удалить store-writer.ts и тесты очереди писателя. Готово.
    • Удалить очистку устаревших ключей среды выполнения и параметры удаления алиасов из upsert/patch строк сессии. Готово.
  1. Удалить поведение JSON-реестра среды выполнения.
    • Сделать чтение и запись реестра песочницы только SQLite. Готово.
    • Импортировать монолитный и сегментированный JSON только на этапе миграции. Готово.
    • Удалить блокировки сегментированного реестра и записи JSON. Готово.
  • Сохранять одну типизированную таблицу реестра вместо хранения строк реестра как универсального непрозрачного JSON, если форма остается операционным состоянием горячего пути. Готово.
  1. Удалить мутацию сессий в форме файловых блокировок.

    • Готово для создания блокировок среды выполнения и API блокировок среды выполнения.
    • Отдельная устаревшая ветка очистки .jsonl.lock в doctor удалена.
    • session.writeLock является устаревшей конфигурацией, мигрируемой doctor, а не типизированной настройкой среды выполнения.
    • Целостность состояния больше не имеет отдельного пути очистки осиротевших файлов транскриптов; миграция doctor импортирует/удаляет устаревшие источники JSONL в одном месте.
    • Координация singleton Gateway использует типизированные строки SQLite state_leases под gateway_locks и больше не раскрывает файлово-блокировочный шов каталога.
    • Универсальное сохранение dedupe Plugin SDK больше не использует файловые блокировки или JSON файлы; оно записывает общие строки состояния Plugin в SQLite. Готово.
    • Координация встраивания QMD использует аренду состояния SQLite вместо qmd/embed.lock. Готово.
  2. Сделать workers осведомленными о базе данных.

    • Workers открывают собственные соединения SQLite.
    • Родитель владеет доставкой, callback каналов и конфигурацией.
    • Worker получает идентификатор агента, идентификатор запуска, режим файловой системы и идентичность реестра БД, а не live-дескрипторы.
    • vfs-only остается экспериментальным и использует базу данных агента как корень хранения.
    • Сначала сохраняйте один worker на активный запуск. Пул может подождать, пока срок жизни соединений БД и поведение отмены не станут простыми.
  3. Интеграция резервного копирования.

    • Научить резервное копирование создавать снимки глобальных и агентских баз данных через SQLite backup или VACUUM INTO. Выполнено для обнаруженных файлов *.sqlite в state asset.
    • Добавить проверку резервных копий на целостность SQLite и версию схемы. Выполнено для создания резервных копий и стандартных проверок целостности архивов.
    • Записывать метаданные запусков резервного копирования в SQLite. Выполнено через общую таблицу backup_runs с путем к архиву, статусом и JSON манифеста.
    • Добавить восстановление из проверенных снимков архивов. Выполнено: openclaw backup restore проверяет перед извлечением, использует нормализованный манифест верификатора, поддерживает --dry-run и требует --yes перед заменой записанных исходных путей.
    • Включать экспорт VFS/рабочей области только по запросу; не экспортировать внутренние данные сеанса как JSON или JSONL.
  4. Удалить устаревшие тесты и код. Выполнено для известных поверхностей runtime-сеансов.

  • Удалить тесты, которые проверяют создание runtime-файлов sessions.json или transcript JSONL. Выполнено для основного хранилища сеансов, чата, событий transcript Gateway, preview, lifecycle, обновлений command session-entry, сброса/трассировки auto-reply и фикстур memory-core dreaming, маршрутизации целей approval, восстановления session transcript, восстановления security permission, экспорта trajectory и экспорта сеансов. Тесты Active-memory transcript теперь проверяют области SQLite и отсутствие создания временных или сохраняемых JSONL-файлов. Старый регрессионный тест heartbeat transcript-pruning удален, потому что runtime больше не усекает JSONL transcripts. Тесты инструмента agent session-list больше не моделируют legacy-пути sessions.json как форму ответа gateway; тесты app/UI/macOS используют databasePath. Тесты использования transcript в /status теперь напрямую заполняют строки SQLite transcript вместо записи JSONL-файлов. Тесты жизненного цикла сеансов Gateway теперь напрямую используют helper-функции заполнения SQLite transcript; старая форма фикстуры однострочного session-file исчезла из покрытия reset и delete. sessions.delete больше не возвращает поле файловой эпохи archived: []; удаление сообщает только результат мутации строки. Старый параметр deleteTranscript тоже удален: удаление сеанса удаляет канонический корень sessions и позволяет SQLite каскадно удалить принадлежащие сеансу строки transcript, snapshot и trajectory, поэтому ни один вызывающий код не может оставить transcript-сироты или забыть ветку cleanup. Тесты захвата trajectory в context-engine теперь читают строки trajectory_runtime_events из изолированной агентской базы данных вместо чтения session.trajectory.jsonl. Скрипты seed для Docker MCP channel теперь напрямую заполняют строки SQLite. Прямые записи sessions.json ограничены фикстурами doctor. Tool Search Gateway E2E читает доказательства tool-call из строк SQLite transcript вместо сканирования файлов agents/<agentId>/sessions/*.jsonl. Host-события memory-core и scratch-строки session-corpus теперь живут в общем SQLite plugin-state; events.jsonl и session-corpus/*.txt являются только legacy-входами миграции doctor. Активные строки используют виртуальные пути memory/session-ingestion/, а не .dreams/session-corpus. Старый модуль восстановления memory-core dreaming и его тесты CLI/Gateway удалены, потому что runtime больше не отвечает за восстановление файлового архива для этого корпуса. Тесты memory-core bridge/public-artifact больше не показывают .dreams/events.jsonl; они используют имя виртуального JSON-артефакта на базе SQLite. Документация по тестированию Public SDK/Codex теперь говорит о состоянии сеансов SQLite вместо файлов сеансов, а пример channel-turn больше не раскрывает аргумент storePath. Состояние Matrix sync теперь напрямую использует хранилище SQLite plugin-state. Активные контракты client/runtime передают корень хранилища аккаунта, а не путь bot-storage.json, и doctor импортирует legacy bot-storage.json в SQLite перед удалением источника. Сценарии QA Matrix restart/destructive теперь напрямую изменяют строку SQLite sync вместо создания или удаления поддельных файлов bot-storage.json, а E2EE substrate передает корень sync-store вместо поддельного пути sync-store.json. Выбор Matrix storage-root больше не оценивает корни по legacy JSON-файлам sync/thread; он использует устойчивые метаданные корня плюс реальное crypto state. Набор тестов runtime SQLite session backend больше не фабрикует sessions.json; legacy-исходные фикстуры теперь находятся в тестах doctor, которые их импортируют. Тесты Gateway session больше не раскрывают helper createSessionStoreDir или неиспользуемую настройку временного пути session-store; каталоги фикстур заданы явно, а прямое создание строк использует именование SQLite session-row. Покрытие doctor-only парсера JSON5 session-store перенесено из infra-тестов в тесты миграции doctor, поэтому runtime-наборы тестов больше не владеют legacy парсингом session-file. Runtime-тесты Microsoft Teams SSO/pending-upload больше не несут JSON sidecar фикстуры или парсеры; legacy-парсинг SSO token живет только в модуле миграции Plugin. Тесты Telegram больше не заполняют поддельные пути хранилища /tmp/*.json; они напрямую сбрасывают SQLite-backed message cache. Общий helper OpenClaw test-state больше не раскрывает legacy writer auth-profiles.json; тесты миграции doctor auth владеют этой фикстурой локально. Runtime-тесты указателей последнего сеанса TUI, exec approvals, переключателей active-memory, проверки Matrix dedupe/startup, синхронизации источника Memory Wiki, привязок current-conversation, onboarding auth и импортов Hermes secret больше не создают старые sidecar-файлы и не проверяют отсутствие старых имен файлов. Они доказывают поведение через строки SQLite и публичные API хранилища; тесты doctor/migration являются единственным местом, где должны быть legacy-имена исходных файлов. Runtime-тесты device/node pairing, channel allowFrom, restart intents, restart handoff, записей session delivery queue, config health, кешей iMessage, cron jobs, заголовков PI transcript, реестров subagent и управляемых image attachments также больше не создают снятые с поддержки файлы JSON/JSONL только для доказательства, что они игнорируются или отсутствуют. PI overflow recovery больше не имеет fallback перезаписи/усечения SessionManager: усечение tool-result и перезаписи context-engine transcript изменяют строки SQLite transcript, затем обновляют активное состояние prompt из базы данных. Сохраняемые добавления сообщений SessionManager делегируют атомарному helper добавления SQLite transcript для выбора родителя и идемпотентности. Обычные добавления metadata/custom entry также выбирают текущего родителя внутри SQLite, поэтому устаревшие экземпляры manager не воскрешают гонки parent-chain до SQLite. Синтетическая очистка PI tail для mid-turn prechecks и sessions_yield теперь напрямую обрезает состояние SQLite transcript; старый мост tail-removal SessionManager и его тесты удалены. Захват checkpoint Compaction также создает снимки только из SQLite; вызывающий код больше не передает живой SessionManager как альтернативный источник transcript.

  • Сохранить тесты, которые заполняют legacy-файлы, только для миграции.

  • Доказательства через JSON-файлы заменены доказательствами через SQL-строки для активных runtime поверхностей.

  • Добавить статические запреты на runtime-записи в legacy JSON-пути сеансов/кеша. Выполнено для repo guard.

  1. Сделать отчет о миграции проверяемым.
    • Записывать запуски миграции в SQLite с отметками времени начала/завершения, исходными путями, хешами источников, счетчиками, предупреждениями и путем резервной копии. Выполнено: выполнения legacy-state migration теперь сохраняют отчет migration_runs с инвентарем исходных путей/таблиц, SHA-256 исходного файла, размерами, счетчиками записей, предупреждениями и путем резервной копии. Выполнено: выполнения legacy-state migration также сохраняют строки migration_sources для аудита на уровне источников и будущих решений skip/backfill.
    • Сделать apply идемпотентным. Повторный запуск после частичного импорта должен либо пропускать уже импортированный источник, либо объединять по стабильному ключу. Выполнено: индексы сеансов, transcripts, delivery queues, plugin state, task ledgers и принадлежащие агенту глобальные строки SQLite импортируются через стабильные ключи или семантику upsert/replace, поэтому повторные запуски объединяют данные без дублирования устойчивых строк.
    • Неудачные импорты должны оставлять исходный файл на месте. Выполнено: неудачные импорты transcript теперь оставляют исходный JSONL-источник по обнаруженному пути, а migration_sources записывает источник как warning с removed_source=0 для следующего запуска doctor.

Правила производительности

  • Одно соединение на поток/процесс допустимо; не разделяйте handles между workers.
  • Используйте WAL, foreign_keys=ON, 30-секундный busy timeout и короткие write-транзакции BEGIN IMMEDIATE.
  • Оставляйте helper-функции write-транзакций синхронными, пока/если async transaction API не добавит явную семантику mutex/backpressure.
  • Делайте записи parent delivery небольшими и транзакционными.
  • Избегайте перезаписи всего хранилища; используйте upsert/delete на уровне строк.
  • Добавьте индексы для путей list-by-agent, list-by-session, updated-at, run id и expiration перед переносом горячего кода.
  • Храните крупные артефакты, медиа и векторы как BLOB или строки chunked BLOB, а не base64 или JSON с числовыми массивами.
  • Держите непрозрачные записи plugin-state небольшими и ограниченными областью.
  • Добавьте SQL cleanup для TTL/expiration вместо очистки файловой системы. Выполнено для runtime-хранилищ, которыми владеет база данных: media, plugin state, plugin blobs, persistent dedupe и agent cache теперь истекают через строки SQLite. Оставшаяся очистка файловой системы ограничена временными материализациями или явными командами удаления.

Статические запреты

Добавьте проверку repo, которая отклоняет новые runtime-записи в legacy state paths:

  • sessions.json
  • *.trajectory.jsonl, кроме материализованных выходных данных support-бандла
  • .acp-stream.jsonl
  • acp/event-ledger.json
  • файлы runtime-кэша cache/*.json
  • agents/<agentId>/agent/auth.json
  • agents/<agentId>/agent/models.json
  • credentials/oauth.json
  • github-copilot.token.json
  • openrouter-models.json
  • auth-profiles.json
  • auth-state.json
  • exec-approvals.json
  • workspace-state.json
  • Matrix credentials*.json и recovery-key.json
  • cron/runs/*.jsonl
  • cron/jobs.json
  • jobs-state.json
  • device-pair-notify.json
  • devices/pending.json
  • devices/paired.json
  • devices/bootstrap.json
  • nodes/pending.json
  • nodes/paired.json
  • identity/device.json
  • identity/device-auth.json
  • push/web-push-subscriptions.json
  • push/vapid-keys.json
  • push/apns-registrations.json
  • process-leases.json
  • gateway-instance-id
  • session-toggles.json
  • Ядро памяти .dreams/events.jsonl
  • Ядро памяти .dreams/session-corpus/
  • Ядро памяти .dreams/daily-ingestion.json
  • Ядро памяти .dreams/session-ingestion.json
  • Ядро памяти .dreams/short-term-recall.json
  • Ядро памяти .dreams/phase-signals.json
  • Ядро памяти .dreams/short-term-promotion.lock
  • Мастерская Skills skill-workshop/<workspace>.json
  • Мастерская Skills skill-workshop/skill-workshop-review-*.json
  • Nostr bus-state-*.json
  • Nostr profile-state-*.json
  • calls.jsonl
  • known-users.json
  • ref-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 для ретрансляции нативных хуков
  • plugin-state/state.sqlite
  • нерегламентированные runtime-сайдкары openclaw-state.sqlite
  • tasks/runs.sqlite
  • tasks/flows/registry.sqlite
  • bindings/current-conversations.json
  • restart-sentinel.json
  • gateway-restart-intent.json
  • gateway-supervisor-restart-handoff.json
  • gateway.<hash>.lock
  • qmd/embed.lock
  • commands.log
  • config-health.json
  • port-guard.json
  • settings/voicewake.json
  • settings/voicewake-routing.json
  • plugin-binding-approvals.json
  • plugins/installs.json
  • audit/file-transfer.jsonl
  • audit/crestodian.jsonl
  • crestodian/rescue-pending/*.json
  • plugins/phone-control/armed.json
  • Вики памяти .openclaw-wiki/log.jsonl
  • Вики памяти .openclaw-wiki/state.json
  • Вики памяти .openclaw-wiki/locks/
  • Вики памяти .openclaw-wiki/source-sync.json
  • Вики памяти .openclaw-wiki/import-runs/*.json
  • Вики памяти .openclaw-wiki/cache/agent-digest.json
  • Вики памяти .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.

Критерии готовности

  • Записи runtime-данных и кэша идут в глобальную или агентскую базу данных SQLite.
  • Runtime больше не записывает индексы сеансов, JSONL транскриптов, JSON реестра песочницы, сайдкар SQLite задач или сайдкар SQLite состояния Plugin. Импортеры невыпущенных сайдкаров SQLite для задач и состояния Plugin удалены.
  • Импорт устаревших файлов выполняется только через doctor.
  • Резервное копирование создает один архив с компактными снимками SQLite и доказательством целостности.
  • Рабочие процессы агента могут запускаться с диском, черновым VFS или экспериментальным хранилищем только на VFS.
  • Конфигурация и явные файлы учетных данных остаются единственными ожидаемыми постоянными управляющими файлами вне базы данных.
  • Проверки репозитория предотвращают повторное введение устаревших runtime-файловых хранилищ.
Was this useful?
On this page

On this page