Get started

بازآرایی وضعیت با اولویت پایگاه داده

بازسازی وضعیت با رویکرد پایگاه‌داده‌محور

تصمیم

از یک چیدمان دوسطحی SQLite استفاده شود:

  • پایگاه‌داده سراسری: ~/.openclaw/state/openclaw.sqlite
  • پایگاه‌داده عامل: یک پایگاه‌داده SQLite برای هر عامل، جهت فضای کاری تحت مالکیت عامل، رونوشت، VFS، آرتیفکت و وضعیت اجرایی بزرگِ مختص هر عامل
  • پیکربندی همچنان مبتنی بر فایل می‌ماند: openclaw.json خارج از پایگاه‌داده باقی می‌ماند. پروفایل‌های احراز هویت زمان اجرا به SQLite منتقل می‌شوند؛ فایل‌های اعتبارنامه ارائه‌دهنده خارجی یا CLI همچنان خارج از پایگاه‌داده OpenClaw و تحت مدیریت مالک باقی می‌مانند.

پایگاه‌داده سراسری، پایگاه‌داده صفحه کنترل است. این پایگاه‌داده مالک کشف عامل، وضعیت مشترک Gateway، جفت‌سازی، وضعیت دستگاه/Node، دفترکل‌های وظیفه و جریان، وضعیت Plugin، وضعیت اجرایی زمان‌بند، فراداده پشتیبان‌گیری و وضعیت مهاجرت است.

پایگاه‌داده عامل، پایگاه‌داده صفحه داده است. این پایگاه‌داده مالک فراداده نشست عامل، جریان رویداد رونوشت، فضای کاری VFS یا فضای نام موقت، آرتیفکت‌های ابزار، آرتیفکت‌های اجرا و داده‌های کش محلی عاملِ قابل جست‌وجو/نمایه‌سازی است.

این ساختار یک نمای سراسری پایدار فراهم می‌کند، بدون آنکه فضاهای کاری بزرگ عامل، رونوشت‌ها و داده‌های موقت دودویی را به مسیر نوشتن مشترک Gateway تحمیل کند.

قرارداد سخت‌گیرانه

این مهاجرت یک شکل متعارف برای زمان اجرا دارد:

  • ردیف‌های نشست فقط فراداده نشست را ماندگار می‌کنند. آن‌ها نباید transcriptLocator، مسیر فایل رونوشت، مسیرهای JSONL همتا، مسیرهای قفل، فراداده هرس یا اشاره‌گرهای سازگاری مربوط به دوران فایل را ماندگار کنند.
  • هویت رونوشت همیشه هویت SQLite است: {agentId, sessionId} به‌همراه فراداده اختیاری موضوع، در مواردی که پروتکل به آن نیاز دارد.
  • sqlite-transcript://... هویت زمان اجرا یا پروتکل نیست. کد جدید نباید مکان‌یاب‌های رونوشت را مشتق، ماندگار، ارسال، تجزیه یا مهاجرت کند. زمان اجرا و آزمون‌ها اصلاً نباید دارای شبه‌مکان‌یاب باشند؛ مستندات فقط برای منع‌کردن آن می‌توانند این رشته را ذکر کنند.
  • sessions.json قدیمی، JSONL رونوشت، .jsonl.lock، هرس، کوتاه‌سازی و منطق قدیمی مسیر نشست فقط به مسیر مهاجرت/درون‌ریزی Doctor تعلق دارند.
  • نام‌های مستعار قدیمی پیکربندی نشست فقط به مهاجرت Doctor تعلق دارند. زمان اجرا session.idleMinutes، session.resetByType.dm یا نام‌های مستعار بین‌عاملی agent:main:* برای نشست اصلیِ عامل پیکربندی‌شده دیگری را تفسیر نمی‌کند.
  • هویت مسیریابی نشست، وضعیت رابطه‌ای نوع‌دار است. مسیرهای داغ زمان اجرا و UI باید sessions.session_scope، sessions.account_id، sessions.primary_conversation_id، conversations و session_conversations را بخوانند؛ آن‌ها نباید session_key را تجزیه کنند یا session_entries.entry_json را برای هویت ارائه‌دهنده واکاوی کنند، مگر به‌عنوان سایه سازگاری هنگام حذف محل‌های فراخوانی قدیمی.
  • نشانگرهای پیام مستقیم در سطح کانال، مانند dm در برابر direct، واژگان مسیریابی هستند، نه مکان‌یاب رونوشت یا دستگیره سازگاری ذخیره‌ساز فایل.
  • پیکربندی قدیمی کنترل‌کننده hook فقط به سطوح هشدار/مهاجرت Doctor تعلق دارد. زمان اجرا نباید hooks.internal.handlers را بارگذاری کند؛ hookها فقط از طریق دایرکتوری‌های hook کشف‌شده و فراداده HOOK.md اجرا می‌شوند.
  • راه‌اندازی زمان اجرا، مسیرهای داغ پاسخ، Compaction، بازنشانی، بازیابی، عیب‌یابی، TTS، hookهای حافظه، زیرعامل‌ها، مسیریابی فرمان Plugin، مرزهای پروتکل و hookها باید {agentId, sessionId} را در سراسر زمان اجرا منتقل کنند.
  • آزمون‌ها باید ردیف‌های رونوشت SQLite را از طریق {agentId, sessionId} مقداردهی اولیه و بررسی کنند. آزمون‌هایی که فقط ارسال مسیر JSONL، حفظ مکان‌یاب ارائه‌شده توسط فراخواننده یا سازگاری فایل رونوشت را اثبات می‌کنند، باید حذف شوند؛ مگر آنکه درون‌ریزی Doctor، مادی‌سازی غیرنشستی برای پشتیبانی/اشکال‌زدایی یا شکل پروتکل را پوشش دهند.
  • runEmbeddedPiAgent(...)، اجراهای worker آماده‌شده و تلاش تعبیه‌شده داخلی نباید مکان‌یاب رونوشت بپذیرند. آن‌ها مدیر رونوشت SQLite را با {agentId, sessionId} باز می‌کنند و آن مدیر را به نشست عامل داخلی‌شده سازگار با PI می‌دهند تا فراخواننده‌های منسوخ نتوانند runner را وادار به نوشتن رونوشت‌های JSON/JSONL کنند.
  • عیب‌یابی runner باید رکوردهای ردگیری زمان اجرا/کش/payload را در SQLite ذخیره کند. عیب‌یابی زمان اجرا نباید گزینه‌های بازنویسی فایل JSONL یا helperهای عمومی برون‌بری JSONL رونوشت را ارائه کند؛ برون‌بری‌های روبه‌کاربر می‌توانند آرتیفکت‌های صریح را از ردیف‌های پایگاه‌داده مادی‌سازی کنند، بدون آنکه نام فایل‌ها را دوباره وارد زمان اجرا کنند.
  • ثبت جریان خام از OPENCLAW_RAW_STREAM=1 به‌همراه ردیف‌های عیب‌یابی SQLite استفاده می‌کند. قرارداد قدیمی ثبت‌کننده فایل pi-mono شامل PI_RAW_STREAM، PI_RAW_STREAM_PATH و raw-openai-completions.jsonl بخشی از زمان اجرا یا آزمون‌های OpenClaw نیست.
  • نمایه‌سازی حافظه QMD نباید رونوشت‌های SQLite را به فایل‌های markdown برون‌بری کند. QMD فقط فایل‌های حافظه پیکربندی‌شده را نمایه‌سازی می‌کند؛ جست‌وجوی رونوشت نشست همچنان مبتنی بر SQLite می‌ماند.
  • زیرمسیر SDK مربوط به QMD، برای کد جدید فقط مخصوص QMD است. helperهای نمایه‌سازی رونوشت نشست SQLite در memory-core-host-engine-session-transcripts قرار دارند؛ هر بازبرون‌بری QMD فقط برای سازگاری است و کد زمان اجرا نباید از آن استفاده کند.
  • نمایه‌های حافظه داخلی در پایگاه‌داده عامل مالک قرار می‌گیرند. پیکربندی زمان اجرا و قراردادهای حل‌شده زمان اجرا نباید memorySearch.store.path را در معرض قرار دهند؛ Doctor آن کلید پیکربندی قدیمی را حذف می‌کند و کد فعلی databasePath عامل را به‌صورت داخلی ارسال می‌کند.

کار پیاده‌سازی باید به حذف کد ادامه دهد تا این گزاره‌ها بدون هیچ استثنایی خارج از مرزهای Doctor/درون‌ریزی/برون‌بری/اشکال‌زدایی برقرار شوند.

وضعیت هدف و پیشرفت

هدف سخت‌گیرانه

  • یک پایگاه‌داده سراسری SQLite مالک وضعیت صفحه کنترل است: state/openclaw.sqlite.
  • یک پایگاه‌داده SQLite برای هر عامل مالک وضعیت صفحه داده است: agents/<agentId>/agent/openclaw-agent.sqlite.
  • پیکربندی همچنان مبتنی بر فایل می‌ماند. openclaw.json بخشی از این بازسازی پایگاه‌داده نیست.
  • فایل‌های قدیمی فقط ورودی‌های مهاجرت Doctor هستند.
  • زمان اجرا هرگز JSONL نشست یا رونوشت را به‌عنوان وضعیت فعال نمی‌نویسد یا نمی‌خواند.

وضعیت‌های هدف

  • not-started: کد زمان اجرای مربوط به دوران فایل همچنان وضعیت فعال را می‌نویسد.
  • migrating: کد Doctor/درون‌ریزی می‌تواند داده‌های فایل را به SQLite منتقل کند.
  • dual-read: پل موقت هم SQLite و هم فایل‌های قدیمی را می‌خواند. این وضعیت برای این بازسازی ممنوع است، مگر آنکه صراحتاً فقط مخصوص Doctor مستند شده باشد.
  • sqlite-runtime: زمان اجرا فقط SQLite را می‌خواند و می‌نویسد.
  • clean: APIها و آزمون‌های قدیمی زمان اجرا حذف می‌شوند و محافظ از پس‌رفت جلوگیری می‌کند.
  • done: مستندات، آزمون‌ها، پشتیبان‌گیری، مهاجرت Doctor و بررسی‌های تغییرات، وضعیت پاک را اثبات می‌کنند.

وضعیت فعلی

  • نشست‌ها: clean برای زمان اجرا. ردیف‌های نشست در پایگاه‌داده هر عامل قرار دارند، APIهای زمان اجرا از {agentId, sessionId} یا {agentId, sessionKey} استفاده می‌کنند و sessions.json ورودی قدیمیِ مختص Doctor است.
  • رونوشت‌ها: clean برای زمان اجرا. رویدادهای رونوشت، هویت‌ها، snapshotها و رویدادهای زمان اجرای مسیر حرکت در پایگاه‌داده هر عامل قرار دارند. زمان اجرا دیگر مکان‌یاب رونوشت یا مسیر رونوشت JSONL را نمی‌پذیرد.
  • runner تعبیه‌شده PI: clean. اجراهای تعبیه‌شده PI، workerهای آماده‌شده، Compaction و حلقه‌های تلاش مجدد از دامنه نشست SQLite استفاده می‌کنند و دستگیره‌های منسوخ رونوشت را رد می‌کنند.
  • Cron: clean برای زمان اجرا. زمان اجرا از cron_jobs و task_runs تحت مالکیت Cron استفاده می‌کند؛ آزمون‌های زمان اجرا از نام‌گذاری SQLite در storeKey استفاده می‌کنند و مسیرهای Cron مربوط به دوران فایل فقط در آزمون‌های مهاجرت قدیمی Doctor باقی می‌مانند.
  • رجیستری وظیفه: clean. ردیف‌های زمان اجرای وظیفه و Task Flow در state/openclaw.sqlite قرار دارند؛ درون‌ریزهای SQLite جانبیِ منتشرنشده حذف شده‌اند.
  • وضعیت Plugin: clean. ردیف‌های وضعیت/blob مربوط به Plugin در پایگاه‌داده سراسری مشترک قرار دارند؛ helperهای قدیمی SQLite جانبیِ وضعیت Plugin با محافظ ممنوع شده‌اند.
  • حافظه: sqlite-runtime برای حافظه داخلی و نمایه‌سازی رونوشت نشست. جدول‌های نمایه حافظه در پایگاه‌داده هر عامل قرار دارند، وضعیت حافظه Plugin از ردیف‌های مشترک وضعیت Plugin استفاده می‌کند و فایل‌های حافظه قدیمی، ورودی‌های مهاجرت Doctor یا محتوای فضای کاری کاربر هستند.
  • پشتیبان‌گیری: sqlite-runtime. پشتیبان‌گیری snapshotهای فشرده SQLite را مرحله‌بندی می‌کند، فایل‌های جانبی زنده WAL/SHM را کنار می‌گذارد، یکپارچگی SQLite را تأیید می‌کند و اجراهای پشتیبان‌گیری را در پایگاه‌داده سراسری ثبت می‌کند.
  • راه‌اندازی فضای کاری: sqlite-runtime. تکمیل راه‌اندازی، گواهی‌های فضای کاری و هش‌های bootstrap تولیدشده در جدول‌های مشترک و نوع‌دار SQLite قرار دارند. زمان اجرا JSON بازنشسته‌شده فضای کاری و فایل‌های جانبی .attested را نمی‌خواند یا نمی‌نویسد؛ Doctor مالک درون‌ریزی اعتبارسنجی‌شده و حذف تأییدشده آن‌ها است.
  • مهاجرت Doctor: migrating، به‌صورت عمدی. Doctor ذخیره‌سازهای قدیمی JSON، JSONL و جانبی بازنشسته‌شده را به SQLite درون‌ریزی می‌کند، اجراها/منابع مهاجرت را ثبت می‌کند و منابع موفق را حذف می‌کند.
  • تأییدیه‌های exec: file-runtime. TypeScript و macOS همچنان exec-approvals.json دایرکتوری وضعیت فعال را می‌خوانند و می‌نویسند؛ شِمای رزروشده exec_approvals_config هنوز مالک زمان اجرا ندارد. انتقال آینده باید درون‌ریزی Doctor با همان وضعیت را اضافه کند و هر دو زمان اجرا را با هم منتقل کند.
  • اسکریپت‌های E2E: clean برای پوشش زمان اجرا. مقداردهی اولیه Docker MCP ردیف‌های SQLite را می‌نویسد. اسکریپت Docker مربوط به زمینه زمان اجرا، JSONL قدیمی را فقط درون داده اولیه مهاجرت Doctor ایجاد می‌کند و مسیر نمایه نشست قدیمی را صراحتاً نام می‌برد.

کارهای باقی‌مانده

  • [x] تغییر نام متغیرهای ذخیره‌ساز آزمون زمان اجرای 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] حذف یا تغییر نام mockهای منسوخ آزمون برون‌بری مربوط به دوران فایل. فایل: src/auto-reply/reply/commands-export-test-mocks.ts. اثبات: rg -n 'resolveSessionFilePath|sessionFile|storePath|transcriptLocator' src/auto-reply/reply.
  • [x] آشکارکردن اینکه داده اولیه قدیمی JSONL در زمینه زمان اجرای Docker فقط مخصوص Doctor است. فایل: 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] اجرای دوباره آزمون‌های متمرکز برای ذخیره‌سازها، فرمان‌ها و اسکریپت‌های تغییریافته. اثبات: 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-session.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، اجرای دروازه تغییرات یا اثبات گسترده از راه دور. اثبات: pnpm check:changed --timed -- <changed extension paths> در اجرای Hetzner Crabbox با شناسه run_3f1cabf6b25c، پس از راه‌اندازی موقت Node 24/pnpm و مسیریابی صریح مسیر برای فضای کاری همگام‌شده فاقد .git، موفق شد.

از پس‌رفت جلوگیری شود

  • بدون مکان‌یاب رونوشت.
  • بدون فایل نشست فعال.
  • بدون fixture جعلی JSONL، به‌جز آزمون‌های مهاجرت قدیمی Doctor.
  • بدون دسترسی خام SQLite در مواردی که Kysely مورد انتظار است.
  • بدون مهاجرت پایگاه‌داده جدید مربوط به دوران فایل. شِمای سراسری در نسخه 1 باقی می‌ماند. شِمای منتشرشده نسخه 1 برای هر عامل، یک مهاجرت محدود زمان اجرا به نسخه 2 برای هویت‌های پایدار منبع حافظه دارد.

فرضیات بررسی کد

هیچ تصمیم محصولی تکمیلی مانع این برنامه نیست. پیاده‌سازی باید با فرضیات زیر ادامه یابد:

  • از node:sqlite مستقیماً استفاده کنید و برای این مسیر ذخیره‌سازی، یک زمان‌اجرای Node ایمن در برابر بازنشانی WAL (22.22.3+، 24.15+، یا 25.9+) الزامی کنید.
  • دقیقاً یک فایل پیکربندی عادی نگه دارید. در این بازآرایی، پیکربندی، مانیفست‌های Plugin یا فضاهای کاری Git را به SQLite منتقل نکنید.
  • فایل‌های سازگاری زمان‌اجرا لازم نیستند. فایل‌های قدیمی JSON و JSONL فقط ورودی‌های مهاجرت هستند. فایل‌های جانبی SQLite محلیِ شاخه هرگز منتشر نشدند و به‌جای درون‌ریزی، حذف می‌شوند.
  • openclaw doctor --fix مالک مهاجرت فایل‌های قدیمی به پایگاه داده است. راه‌اندازی زمان‌اجرا فقط مالک ارتقاهای محدود میان نسخه‌های منتشرشده طرح‌واره SQLite است؛ و نباید وضعیت دوران فایل را درون‌ریزی کند.
  • سازگاری اطلاعات احراز هویت از همین قاعده پیروی می‌کند: اطلاعات احراز هویت زمان‌اجرا در SQLite قرار می‌گیرند. فایل‌های قدیمی auth-profiles.json، فایل‌های مختص هر عامل auth.json و فایل‌های مشترک credentials/oauth.json ورودی‌های مهاجرت doctor هستند و سپس پس از درون‌ریزی حذف می‌شوند.
  • وضعیت کاتالوگ مدل تولیدشده بر پایگاه داده متکی است. کد زمان‌اجرا نباید در agents/<agentId>/agent/models.json بنویسد؛ فایل‌های موجود models.json ورودی‌های قدیمی doctor هستند و پس از درون‌ریزی در agent_model_catalogs حذف می‌شوند.
  • زمان‌اجرا نباید مکان‌یاب‌های رونوشت را مهاجرت دهد، نرمال‌سازی کند یا میان آن‌ها پل بزند. هویت رونوشت فعال در SQLite برابر {agentId, sessionId} است. مسیرهای فایل فقط ورودی‌های قدیمی 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 را حذف می‌کنند؛ موتورهایی که نمی‌توانند پارامترهای فعلی مبتنی‌بر پایگاه داده را بپذیرند باید با خطای آشکار متوقف شوند، نه اینکه برایشان پل ایجاد شود.
  • خروجی پشتیبان باید یک فایل بایگانی باقی بماند. محتوای پایگاه داده باید به‌صورت تصویرهای لحظه‌ای فشرده SQLite وارد آن بایگانی شود، نه فایل‌های جانبی خام و زنده WAL.
  • جست‌وجوی رونوشت مفید است، اما برای نخستین برش مبتنی‌بر پایگاه داده الزامی نیست. طرح‌واره را طوری طراحی کنید که بتوان FTS را بعداً افزود.
  • اجرای Worker باید تا زمان تثبیت مرز پایگاه داده، پشت تنظیمات به‌صورت آزمایشی باقی بماند.

یافته‌های بررسی کد

شاخه فعلی از مرحله اثبات مفهوم عبور کرده است. پایگاه داده مشترک وجود دارد، node:sqlite متعلق به Node از طریق یک یاریگر کوچک زمان‌اجرا متصل شده است و ذخیره‌گاه‌های پیشین اکنون در state/openclaw.sqlite یا پایگاه داده openclaw-agent.sqlite متعلق به مالک می‌نویسند.

کار باقی‌مانده انتخاب SQLite نیست؛ بلکه تمیز نگه‌داشتن مرز جدید و حذف هرگونه رابط سازگاری‌مانندی است که هنوز به دنیای قدیمی فایل‌ها شباهت دارد:

  • storePath نشست دیگر هویت زمان‌اجرا، شکل فیکسچر آزمون یا فیلد محموله وضعیت نیست. آزمون‌های زمان‌اجرا و پل دیگر شامل نام قرارداد storePath نیستند؛ کد doctor/مهاجرت مالک آن واژگان قدیمی است.
  • نوشتن‌های نشست دیگر از صف قدیمی درون‌فرایندی store-writer.ts عبور نمی‌کنند. نوشتن‌های وصله SQLite خارج از تراکنش آماده می‌شوند، سپس از یک تراکنش کوتاه و همگامِ اعتبارسنجی/اعمال با تشخیص صریح تعارض استفاده می‌کنند.
  • کشف مسیرهای قدیمی هنوز کاربردهای معتبری در مهاجرت دارد، اما کد زمان‌اجرا باید دیگر sessions.json و فایل‌های JSONL رونوشت را هدف‌های احتمالی نوشتن تلقی نکند.
  • جدول‌های متعلق به عامل در پایگاه‌های داده SQLite مختص هر عامل قرار می‌گیرند. پایگاه داده سراسری ردیف‌های رجیستری/صفحه کنترل را نگه می‌دارد؛ هویت رونوشت در ردیف‌های رونوشت مختص هر عامل برابر {agentId, sessionId} است. کد زمان‌اجرا نباید مسیرهای فایل رونوشت را ماندگار کند یا مکان‌یاب‌های رونوشت را مهاجرت دهد.
  • doctor از قبل چندین فایل قدیمی را درون‌ریزی می‌کند. پاک‌سازی لازم این است که آن را به یک پیاده‌سازی صریح و واحد مهاجرت تبدیل کنیم که doctor آن را فراخوانی کند، همراه با یک گزارش ماندگار مهاجرت.

هیچ پرسش محصولی دیگری مانع پیاده‌سازی نیست.

شکل فعلی کد

این شاخه از قبل یک پایه مشترک و واقعی SQLite دارد:

  • حداقل نسخهٔ زمان اجرا اکنون به یک بیلد Node ایمن در برابر بازنشانی WAL نیاز دارد: 22.22.3+، 24.15+، یا 25.9+. package.json، محافظ زمان اجرای CLI، پیش‌فرض‌های نصب‌کننده، مکان‌یاب زمان اجرا در macOS، CI و مستندات عمومی نصب همگی با یکدیگر هم‌نظرند.
  • src/state/openclaw-state-db.ts، openclaw.sqlite را باز می‌کند، WAL، synchronous=NORMAL، busy_timeout=30000 و foreign_keys=ON را تنظیم می‌کند و ماژول طرح‌وارهٔ تولیدشده از src/state/openclaw-state-schema.sql را اعمال می‌کند.
  • نوع‌های جدول Kysely و ماژول‌های طرح‌وارهٔ زمان اجرا از پایگاه‌های دادهٔ موقت SQLite تولید می‌شوند که از فایل‌های ثبت‌شدهٔ .sql ساخته شده‌اند؛ کد زمان اجرا دیگر رشته‌های طرح‌وارهٔ کپی‌وچسبانده‌شده را برای پایگاه‌های دادهٔ سراسری، مختص هر عامل یا ثبت پراکسی نگه نمی‌دارد.
  • ذخیره‌گاه‌های زمان اجرا، نوع‌های ردیف انتخاب‌شده و درج‌شده را از رابط‌های تولیدشدهٔ Kysely با نام DB استخراج می‌کنند، به‌جای آنکه شکل ردیف‌های SQLite را دستی بازتعریف کنند. SQL خام همچنان به اعمال طرح‌واره، pragmaها و DDL مخصوص مهاجرت محدود است.
  • طرح‌وارهٔ سراسری SQLite همچنان در user_version = 1 باقی می‌ماند. طرح‌وارهٔ مختص هر عامل در نسخهٔ 2 است؛ بازکنندهٔ آن کلید منبع حافظهٔ نسخهٔ عرضه‌شدهٔ 1 را به‌صورت اتمی به یک شناسهٔ عدد صحیح پایدار مهاجرت می‌دهد. واردکردن از فایل به پایگاه داده همچنان در کد doctor باقی می‌ماند.
  • مالکیت رابطه‌ای در جایی اعمال می‌شود که مرز مالکیت معیار است: ردیف‌های مهاجرت منبع از migration_runs به‌صورت آبشاری حذف می‌شوند، وضعیت تحویل وظیفه از task_runs به‌صورت آبشاری حذف می‌شود و ردیف‌های هویت رونوشت از رویدادهای رونوشت به‌صورت آبشاری حذف می‌شوند.
  • جدول‌های اشتراکی فعلی شامل agent_databases، auth_profile_stores، auth_profile_state، plugin_state_entries، plugin_blob_entries، media_blobs، skill_uploads، capture_sessions، capture_events، capture_blobs، sandbox_registry_entries، cron_jobs، commitments، delivery_queue_entries، model_capability_cache، workspace_setup_state، workspace_path_aliases، workspace_attestations، workspace_generated_bootstrap_hashes، 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، جدول‌های نوع‌دار متعلق به میزبان دریافت نمی‌کند. Pluginهای نصب‌شده از plugin_state_entries برای محموله‌های JSON نسخه‌دار و از plugin_blob_entries برای بایت‌ها استفاده می‌کنند، همراه با مالکیت فضای نام/کلید، پاک‌سازی TTL، پشتیبان‌گیری و سوابق مهاجرت Plugin. وضعیت هماهنگ‌سازی Plugin که متعلق به میزبان است، در صورتی که قرارداد پرس‌وجو در مالکیت میزبان باشد، همچنان می‌تواند جدول‌های نوع‌دار داشته باشد؛ مانند plugin_binding_approvals.
  • مهاجرت‌های Plugin، مهاجرت داده روی فضاهای نام متعلق به Plugin هستند، نه مهاجرت طرح‌وارهٔ میزبان. یک Plugin می‌تواند ورودی‌های وضعیت/بلاب نسخه‌دار خود را از طریق ارائه‌دهندهٔ مهاجرت منتقل کند و میزبان، وضعیت منبع/اجرا را در دفترکل عادی مهاجرت ثبت می‌کند. نصب Pluginهای جدید نیازی به تغییر openclaw-state-schema.sql ندارد، مگر آنکه خود میزبان مالکیت یک قرارداد جدید میان‌Pluginی را بر عهده بگیرد.
  • src/state/openclaw-agent-db.ts، agents/<agentId>/agent/openclaw-agent.sqlite را باز می‌کند، پایگاه داده را در پایگاه دادهٔ سراسری ثبت می‌کند و مالک جدول‌های محلی عامل برای نشست، رونوشت، VFS، مصنوع، حافظهٔ نهان و نمایهٔ حافظه است. کشف اشتراکی زمان اجرا اکنون رجیستری نوع‌دارِ تولیدشدهٔ agent_databases را می‌خواند، به‌جای آنکه آن پرس‌وجو را در هر محل فراخوانی دوباره پیاده‌سازی کند.
  • پایگاه‌های دادهٔ سراسری و مختص هر عامل یک ردیف schema_meta را با نقش پایگاه داده، نسخهٔ طرح‌واره، برچسب‌های زمانی و شناسهٔ عامل برای پایگاه‌های دادهٔ عامل ثبت می‌کنند. پایگاه دادهٔ سراسری همچنان در user_version = 1 باقی می‌ماند؛ پایگاه‌های دادهٔ مختص هر عامل پس از مهاجرت محدود هویت منبع حافظه از نسخهٔ 2 استفاده می‌کنند.
  • هویت نشست مختص هر عامل اکنون یک جدول ریشهٔ معیار sessions دارد که کلید آن session_id است و شامل session_key، session_scope، account_id، primary_conversation_id، برچسب‌های زمانی، فیلدهای نمایشی، فرادادهٔ مدل، شناسهٔ مهار و پیوند والد/ایجادشده به‌صورت ستون‌های قابل پرس‌وجو است. session_routes نمایهٔ یکتای مسیر فعال از session_key به session_id فعلی است، بنابراین یک کلید مسیر می‌تواند به یک نشست ماندگار تازه منتقل شود، بدون آنکه خواندن‌های داغ مجبور باشند میان ردیف‌های تکراری sessions.session_key انتخاب کنند. محمولهٔ قدیمی با شکل سازگاری session_entries.entry_json از طریق کلید خارجی به ریشهٔ ماندگار session_id متصل است؛ این محموله دیگر تنها نمایش یک نشست در سطح طرح‌واره نیست.
  • هویت مکالمهٔ خارجی مختص هر عامل نیز رابطه‌ای است: conversations هویت نرمال‌شدهٔ ارائه‌دهنده/حساب/مکالمه را ذخیره می‌کند و session_conversations یک نشست OpenClaw را به یک یا چند مکالمهٔ خارجی پیوند می‌دهد. این ساختار نشست‌های پیام مستقیم shared-main را پوشش می‌دهد که در آن‌ها چند همتا می‌توانند عمداً به یک نشست نگاشت شوند، بدون ثبت اطلاعات نادرست در session_key. SQLite همچنین یکتایی هویت طبیعی ارائه‌دهنده را اعمال می‌کند تا یک چندتایی یکسان کانال/حساب/نوع/همتا/رشته نتواند میان شناسه‌های مکالمه منشعب شود. همتاهای مستقیم shared-main با نقش participant پیوند داده می‌شوند، بنابراین یک نشست OpenClaw می‌تواند چند همتای خارجی پیام مستقیم را نمایش دهد، بدون آنکه همتاهای قدیمی‌تر را به ردیف‌های مرتبط مبهم تنزل دهد. sessions.primary_conversation_id همچنان به هدف تحویل نوع‌دار فعلی اشاره می‌کند. ستون‌های بستهٔ مسیریابی/وضعیت با محدودیت‌های CHECK در SQLite اعمال می‌شوند، به‌جای آنکه فقط به unionهای TypeScript تکیه کنند. پروجکشن نشست زمان اجرا، سایه‌های مسیریابی سازگاری را از session_entries.entry_json پیش از اعمال ستون‌های نوع‌دار نشست/مکالمه پاک می‌کند، بنابراین محموله‌های JSON کهنه نمی‌توانند اهداف تحویل را دوباره زنده کنند. مسیریابی اعلام عامل فرعی نیز به زمینهٔ تحویل نوع‌دار SQLite نیاز دارد؛ دیگر به فیلدهای مسیر سازگاری SessionEntry بازنمی‌گردد. وراثت صریح تحویل chat.send در Gateway، زمینهٔ تحویل نوع‌دار SQLite را به‌جای فیلدهای سازگاری origin/last* می‌خواند. tools.effective نیز زمینهٔ ارائه‌دهنده/حساب/رشته را از ردیف‌های نوع‌دار تحویل/مسیریابی SQLite استخراج می‌کند، نه از سایه‌های کهنهٔ ورودی نشست last*. زمینهٔ اعلان رویداد سیستم، فیلدهای کانال/مقصد/حساب/رشته را از فیلدهای نوع‌دار تحویل بازسازی می‌کند، نه از سایه‌های origin. ابزار کمکی اشتراکی deliveryContextFromSession و نگاشت‌گر نشست به مکالمه اکنون SessionEntry.origin را کاملاً نادیده می‌گیرند؛ فقط فیلدهای نوع‌دار تحویل و ردیف‌های رابطه‌ای مکالمه می‌توانند هویت مسیر داغ ایجاد کنند. نرمال‌سازی ورودی نشست زمان اجرا، پیش از ماندگارکردن یا پروجکت‌کردن entry_json، origin را حذف می‌کند و نوشتن فرادادهٔ ورودی، فیلدهای نوع‌دار کانال/گفت‌وگو را همراه با ردیف‌های رابطه‌ای مکالمه می‌نویسد، به‌جای آنکه سایه‌های مبدأ جدید ایجاد کند.
  • رویدادهای رونوشت، اسنپ‌شات‌های رونوشت و رویدادهای زمان اجرای مسیر حرکت اکنون به ریشهٔ معیار مختص هر عامل sessions ارجاع می‌دهند و با حذف نشست به‌صورت آبشاری حذف می‌شوند. ردیف‌های هویت/تکرارناپذیری رونوشت همچنان از همان ردیف دقیق رویداد رونوشت به‌صورت آبشاری حذف می‌شوند.
  • نمایه‌های هستهٔ حافظه اکنون از جدول‌های صریح پایگاه دادهٔ عامل memory_index_meta، memory_index_sources، memory_index_chunks و memory_embedding_cache استفاده می‌کنند و memory_index_state تغییرات بازبینی را ردیابی می‌کند. نمایه‌های جانبی اختیاری FTS/بردار به‌جای جدول‌های عمومی meta، files، chunks، chunks_fts یا chunks_vec، با نام‌های memory_index_chunks_fts و memory_index_chunks_vec نام‌گذاری شده‌اند. نام‌های معیار، شکل فعلی ردیف مسیر/منبع و سازگاری تعبیهٔ سریال‌شده را حفظ می‌کنند. این جدول‌ها حافظهٔ نهان مشتق‌شده/جست‌وجو هستند، نه ذخیره‌گاه معیار رونوشت؛ می‌توان آن‌ها را حذف کرد و از فایل‌های فضای کاری حافظه و منابع پیکربندی‌شده دوباره ساخت. بازکردن یک نمایهٔ حافظه با نام عمومیِ عرضه‌شده، فراداده، منابع، قطعه‌ها و حافظهٔ نهان تعبیهٔ آن را به جدول‌های معیار مهاجرت می‌دهد؛ جدول‌های مشتق‌شدهٔ FTS/بردار با نام‌های معیار خود دوباره ساخته می‌شوند.
  • وضعیت بازیابی اجرای عامل فرعی اکنون در ردیف‌های اشتراکی نوع‌دار subagent_runs با کلیدهای نمایه‌شدهٔ نشست فرزند، درخواست‌کننده و کنترل‌کننده نگهداری می‌شود. فایل قدیمی subagents/runs.json فقط ورودی پاک‌سازی Doctor است. ورودی‌های اجرای آن وضعیت بازیابی موقتی هستند، بنابراین Doctor رسید بازنشستگی را ثبت می‌کند و فایل را بدون واردکردن دور می‌اندازد. چون پس از هرس‌شدن ردیف‌های SQLite، یک فایل نمی‌تواند اثبات کند ورودی‌هایش فعال‌اند یا کهنه، اپراتورها باید پیش از ارتقا در این مرز اجازه دهند اجراهای فعال دورهٔ فایل پایان یابند.
  • اتصال‌های فعلی مکالمه اکنون در ردیف‌های اشتراکی نوع‌دار current_conversation_bindings با کلید شناسهٔ نرمال‌شدهٔ مکالمه نگهداری می‌شوند و ستون‌های عامل/نشست هدف، نوع مکالمه، وضعیت، انقضا و فراداده به‌صورت ستون‌های رابطه‌ای ذخیره می‌شوند، نه یک رکورد اتصال مبهم و تکراری. کلید اتصال ماندگار شامل نوع نرمال‌شدهٔ مکالمه است تا ارجاع‌های مستقیم/گروه/کانال با یکدیگر تداخل نکنند و SQLite مقادیر نامعتبر نوع/وضعیت اتصال را رد می‌کند. فایل قدیمی bindings/current-conversations.json فقط ورودی مهاجرت doctor است.
  • بازیابی صف تحویل اکنون ستون‌های نوع‌دار صف برای کانال، هدف، حساب، نشست، تلاش مجدد، خطا، ارسال پلتفرم و وضعیت بازیابی را روی JSON بازپخش قرار می‌دهد. entry_json محموله‌های بازپخش، هوک‌ها و محمولهٔ قالب‌بندی را نگه می‌دارد، اما ستون‌های نوع‌دار مرجع معتبر برای مسیریابی/وضعیت داغ صف هستند.
  • اشاره‌گرهای بازیابی آخرین نشست TUI اکنون در ردیف‌های اشتراکی نوع‌دار tui_last_sessions با کلید دامنهٔ هش‌شدهٔ اتصال/نشست TUI نگهداری می‌شوند. زمان اجرا فقط SQLite را می‌خواند و می‌نویسد، هر دامنه را به‌صورت اتمی upsert می‌کند و نشست‌های Heartbeat را مستثنا می‌کند. openclaw doctor --fix فایل JSON قدیمی TUI را به‌طور سخت‌گیرانه اعتبارسنجی می‌کند، ردیف‌های جدیدتر SQLite را نگه می‌دارد، نتیجهٔ معیار را تأیید می‌کند و فایل قدیمیِ بدون تغییر را به‌جای باقی‌گذاشتن بایگانی حذف می‌کند.
  • هش‌های استقرار فرمان Discord اکنون در ذخیره‌گاه اشتراکی SQLite وضعیت Plugin نگهداری می‌شوند. زمان اجرا فقط کلیدهای دقیق با دامنهٔ برنامه را می‌خواند و می‌نویسد. Doctor فایل قدیمی و قابل‌بازسازی discord/command-deploy-cache.json را بدون واردکردن حذف می‌کند، بنابراین راه‌اندازی بعدی یک تطبیق معیار انجام می‌دهد.
  • ترجیحات پیش‌فرض TTS اکنون در ردیف‌های اشتراکی SQLite وضعیت Plugin با کلیدهای زیر Plugin speech-core نگهداری می‌شوند. فایل قدیمی settings/tts.json فقط ورودی مهاجرت doctor است؛ زمان اجرا دیگر فایل‌های JSON ترجیحات TTS را نمی‌خواند یا نمی‌نویسد و حل‌کنندهٔ مسیر قدیمی در ماژول مهاجرت doctor قرار دارد.
  • فرادادهٔ هدف راز اکنون به‌جای وانمودکردن به اینکه هر هدف اعتبارنامه یک فایل پیکربندی است، دربارهٔ ذخیره‌گاه‌ها صحبت می‌کند. openclaw.json همچنان ذخیره‌گاه پیکربندی است؛ اهداف نمایهٔ احراز هویت از ردیف‌های نوع‌دار SQLite با نام auth_profile_stores استفاده می‌کنند و اعتبارنامه‌های شکل‌گرفته بر اساس ارائه‌دهنده به‌صورت محموله‌های JSON نگهداری می‌شوند.
  • ممیزی راز دیگر فایل‌های بازنشستهٔ مختص هر عامل auth.json را اسکن نمی‌کند. Doctor مالک هشدار دربارهٔ آن فایل قدیمی، واردکردن آن و حذف آن است.
  • ابزارهای کمکی مسیر نمایهٔ احراز هویت قدیمی اکنون در کد قدیمی doctor قرار دارند. ابزارهای کمکی مسیر نمایهٔ احراز هویت هسته، هویت ذخیره‌گاه احراز هویت SQLite و مکان‌های نمایشی را ارائه می‌کنند، نه مسیرهای زمان اجرای auth-profiles.json یا auth-state.json.
  • ماژول‌های زمان اجرای بازیابی اجرای عامل فرعی و حافظهٔ نهان قابلیت مدل OpenRouter اکنون خواننده‌ها/نویسنده‌های اسنپ‌شات SQLite را از ابزارهای کمکی واردکردن JSON قدیمیِ مخصوص doctor جدا نگه می‌دارند. قابلیت‌های OpenRouter به‌جای یک بلاب حافظهٔ نهان مبهم یا جدول میزبان مخصوص ارائه‌دهنده، از ردیف‌های عمومی نوع‌دار model_capability_cache زیر provider_id = "openrouter" استفاده می‌کنند. taskName اجرای عامل فرعی در ستون نوع‌دار subagent_runs.task_name ذخیره می‌شود؛ نسخهٔ payload_json دادهٔ بازپخش/اشکال‌زدایی است، نه منبع فیلدهای نمایش یا جست‌وجوی داغ.
  • src/agents/filesystem/virtual-agent-fs.sqlite.ts یک VFS مبتنی بر SQLite را روی جدول vfs_entries پایگاه دادهٔ عامل پیاده‌سازی می‌کند. خواندن دایرکتوری، خروجی‌گیری بازگشتی، حذف و تغییر نام از بازه‌های پیشوندی نمایه‌شدهٔ (namespace, path) استفاده می‌کنند، به‌جای آنکه کل فضای نام را اسکن کنند یا به تطبیق مسیر LIKE متکی باشند.
  • src/agents/runtime-worker.entry.ts برای workerها به‌ازای هر اجرا، VFS مبتنی بر SQLite، مخزن آرتیفکت ابزار، مخزن آرتیفکت اجرا و مخازن کش با دامنهٔ محدود ایجاد می‌کند.
  • اکنون تکمیل راه‌اندازی اولیهٔ فضای کاری، تازگی گواهی و هش‌های راه‌اندازی اولیهٔ تولیدشده در ردیف‌های اشتراکی و نوع‌دار workspace_setup_state، workspace_path_aliases، workspace_attestations و workspace_generated_bootstrap_hashes که با هویت کانونی فضای کاری کلیدگذاری شده‌اند، نگهداری می‌شوند. نام‌های مستعار واژگانی و مسیر واقعیِ ماندگار، پس از ناپدیدشدن یک پیوند نمادین پیکربندی‌شده، حفاظت از فضای کاری ناپدیدشده را پایدار نگه می‌دارند؛ نام‌های مستعار تغییرمقصد‌یافته به‌صورت بسته شکست می‌خورند. زمان اجرا دیگر openclaw-workspace-state.json، .openclaw/workspace-state.json، workspace-attestations/*.attested در دایرکتوری وضعیت یا فایل‌های جانبی هم‌سطح <workspace>.attested را نمی‌خواند یا نمی‌نویسد. openclaw doctor --fix منابع قدیمی را اعتبارسنجی و تصاحب می‌کند، آن‌ها را همراه با رسیدهای مهاجرت به SQLite وارد می‌کند، ردیف‌های کانونی را راستی‌آزمایی می‌کند و تنها پس از آن فایل‌های تصاحب‌شده را حذف می‌کند.
  • طرح‌وارهٔ اشتراکی یک ردیف یکتای exec_approvals_config رزرو می‌کند، اما گذار زمان اجرا همچنان در انتظار است. TypeScript و برنامهٔ همراه macOS هنوز از فایل JSON محدود به وضعیت استفاده می‌کنند و باید با هم به SQLite منتقل شوند.
  • هویت دستگاه TypeScript اکنون از ردیف‌های نوع‌دار device_identities استفاده می‌کند و واردکردن JSON قدیمیِ مختص doctor خارج از مالک زمان اجرا نگه داشته شده است. احراز هویت دستگاه تا زمان انجام یک مهاجرت هماهنگ طرح‌واره و میان‌زمان‌اجرایی، همچنان مبتنی بر فایل است؛ device_auth_tokens برای آن کار بعدی رزرو می‌ماند.
  • کش تبادل توکن 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#table/device_identities و کلیدهای ردیف برای هویت دستگاه استفاده می‌کند. فایل‌های قدیمی کانتینر Apple توسط مالک مهاجرت Swift وارد می‌شوند، زیرا Doctor مبتنی بر TypeScript نمی‌تواند به آن کانتینرها دسترسی داشته باشد. احراز هویت دستگاه در Swift تا زمان کار هماهنگ بعدی روی احراز هویت، همچنان مبتنی بر فایل است.
  • هویت دستگاه Android و احراز هویت کش‌شدهٔ دستگاه همچنان مخازن محلی برنامه هستند. آن‌ها به مهاجرتی جداگانه و متعلق به Android نیاز دارند؛ ادعاهای SQLite میزبان رفتار فعلی Android را توصیف نمی‌کنند.
  • تاریخچهٔ بسته‌های اخیر اعلان‌های Android از ردیف‌های نوع‌دار android_notification_recent_packages استفاده می‌کند. زمان اجرا دیگر کلیدهای CSV قدیمی SharedPreferences را مهاجرت نمی‌دهد یا نمی‌خواند.
  • ایجاد هویت دستگاه هنگامی که identity/device.json قدیمی وجود دارد، ردیف هویت SQLite نامعتبر است یا مخزن هویت SQLite باز نمی‌شود، به‌صورت بسته شکست می‌خورد. Doctor ابتدا آن فایل را وارد و حذف می‌کند، بنابراین راه‌اندازی زمان اجرا نمی‌تواند پیش از مهاجرت، هویت جفت‌سازی را بی‌سروصدا تغییر دهد.
  • انتخاب هویت دستگاه یک کلید ردیف SQLite است، نه مکان‌یاب فایل JSON. آزمون‌ها و helperهای 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 زیر src/commands/doctor/legacy/oauth-profile-ids.ts قرار دارد.
  • فرمان‌های غیر doctor تعمیر پیکربندی قدیمی را خودکار اجرا نمی‌کنند. برای نمونه، openclaw update --channel اکنون در برابر پیکربندی قدیمی نامعتبر شکست می‌خورد و از کاربر می‌خواهد doctor را اجرا کند، به‌جای آنکه کد مهاجرت doctor را بی‌سروصدا وارد کند.
  • Web push،‏ APNs،‏ Voice Wake، بررسی‌های به‌روزرسانی و سلامت پیکربندی اکنون به‌جای blobهای مبهم و کامل JSON، از جدول‌های اشتراکی و نوع‌دار SQLite برای اشتراک‌ها، کلیدهای VAPID، ثبت‌های Node، ردیف‌های محرک، ردیف‌های مسیریابی، وضعیت اعلان به‌روزرسانی و ورودی‌های سلامت پیکربندی استفاده می‌کنند. نوشتن‌های Web Push و APNs فقط ردیف کلید اصلیِ تحت‌تأثیر را upsert می‌کنند؛ سلامت پیکربندی براساس مسیر پیکربندی تطبیق داده می‌شود. ماژول‌های زمان اجرای آن‌ها از helperهای واردکردن JSON قدیمیِ مختص Doctor جدا باقی می‌مانند.
  • زمان اجرای APNs فقط apns_registrations را می‌خواند و می‌نویسد. openclaw doctor --fix صریح، push/apns-registrations.json منسوخ‌شده را به‌طور سخت‌گیرانه وارد می‌کند، ردیف‌های کانونی موجود را حفظ می‌کند، تراکنش را راستی‌آزمایی می‌کند، رسیدی ثبت می‌کند و JSON حاوی اطلاعات محرمانه را حذف می‌کند. تلاش‌های مجدد مبتنی بر رسید فقط پاک‌سازی را انجام می‌دهند، درحالی‌که apns_registration_tombstones ابطال‌های پیش از نخستین تعمیر را پوشش می‌دهند تا مجوزهای قدیمی relay یا توکن‌های دستگاه نتوانند دوباره فعال شوند.
  • پیکربندی میزبان Node اکنون از یک ردیف یکتای نوع‌دار در پایگاه‌دادهٔ اشتراکی SQLite استفاده می‌کند. تا زمانی که فایل قدیمی node.json یا یک تصاحب نیمه‌تمام باقی باشد، زمان اجرا به‌صورت بسته شکست می‌خورد؛ openclaw doctor --fix صریح آن را به‌طور سخت‌گیرانه وارد و حذف می‌کند و سپس استفادهٔ عادی زمان اجرا آغاز می‌شود.
  • جفت‌سازی دستگاه/Node، جفت‌سازی کانال، فهرست‌های مجاز کانال و وضعیت راه‌اندازی اولیه اکنون به‌جای blobهای مبهم و کامل JSON از ردیف‌های نوع‌دار SQLite استفاده می‌کنند. تأییدهای اتصال Plugin و وضعیت کارهای Cron نیز از همین تفکیک پیروی می‌کنند: ماژول‌های زمان اجرا عملیات مبتنی بر SQLite و helperهای خنثی snapshot را ارائه می‌کنند، و نوشتن snapshotهای جفت‌سازی/راه‌اندازی اولیه و تأیید اتصال Plugin به‌جای خالی‌کردن جدول‌ها، ردیف‌ها را براساس کلید اصلی تطبیق می‌دهد؛ در همین حال doctor فایل‌های JSON قدیمی را از طریق ماژول‌های src/commands/doctor/legacy/* وارد/حذف می‌کند.
  • رکوردهای Plugin نصب‌شده اکنون در نمایهٔ Pluginهای نصب‌شدهٔ SQLite قرار دارند. خواندن/نوشتن پیکربندی زمان اجرا دیگر دادهٔ قدیمی پیکربندی تألیفی plugins.installs را مهاجرت نمی‌دهد یا حفظ نمی‌کند؛ doctor آن شکل پیکربندی قدیمی را پیش از استفادهٔ عادی زمان اجرا به SQLite وارد می‌کند.
  • snapshotهای بازیابی اعتبارنامهٔ QQBot اکنون در وضعیت Plugin مبتنی بر SQLite زیر qqbot/credential-backups قرار دارند. زمان اجرا دیگر qqbot/data/credential-backup*.json را نمی‌نویسد؛ قرارداد doctor در QQBot آن فایل‌های پشتیبان قدیمی را از دایرکتوری وضعیت فعال وارد و بایگانی می‌کند.
  • برنامه‌ریزی بارگذاری مجدد Gateway، snapshotهای نمایهٔ Pluginهای نصب‌شدهٔ SQLite را زیر فضای نام داخلی diff با نام installedPluginIndex.installRecords.* مقایسه می‌کند. تصمیم‌های بارگذاری مجدد زمان اجرا دیگر آن ردیف‌ها را در اشیای پیکربندی جعلی plugins.installs قرار نمی‌دهند.
  • اعتبارنامه‌های حساب Matrix اکنون در وضعیت Plugin مبتنی بر SQLite قرار دارند. زمان اجرا فقط همان مخزن کانونی را می‌خواند؛ Doctor فایل‌های منسوخ‌شدهٔ credentials/matrix/credentials*.json را، هنگامی که حسابشان قابل شناسایی باشد، وارد، راستی‌آزمایی و بایگانی می‌کند.
  • ماژول‌های اصلی زمان اجرای جفت‌سازی و Cron دیگر از سازنده‌های قدیمی مسیر JSON استفاده نمی‌کنند. helper منسوخ‌شدهٔ مسیر جفت‌سازی SDK فقط برای سازگاری مهاجرت باقی مانده است؛ مهاجرت وضعیت doctor مالک خواندن و واردکردن فایل‌های آن است. ماژول‌های قدیمیِ متعلق به Doctor، مسیرهای منبع pending.json، paired.json، bootstrap.json و cron/jobs.json را فقط برای آزمون‌های واردکردن و مهاجرت می‌سازند. عادی‌سازی قدیمی شکل کار Cron و واردکردن تاریخچهٔ JSONL زیر src/commands/doctor/cron/ قرار دارد؛ نهایی‌سازی تاریخچهٔ قدیمی SQLite هنگام بازشدن پایگاه‌دادهٔ وضعیت اجرا می‌شود.
  • src/commands/doctor/legacy/runtime-state.ts فایل‌های قدیمی وضعیت JSON، از جمله پیکربندی میزبان Node، را از doctor به SQLite وارد می‌کند. واردکننده‌های جدید فایل‌های قدیمی زیر src/commands/doctor/legacy/ باقی می‌مانند.
  • src/commands/doctor/state-migrations.ts رونوشت‌های قدیمی sessions.json و *.jsonl را مستقیماً به SQLite وارد می‌کند و منابع با واردکردن موفق را حذف می‌کند. این بخش دیگر رونوشت‌های قدیمی ریشه را از طریق agents/<agentId>/sessions/*.jsonl مرحله‌بندی نمی‌کند و پیش از واردکردن، مقصد کانونی JSONL نمی‌سازد.
  • بررسی‌های doctor برای یکپارچگی وضعیت دیگر دایرکتوری‌های قدیمی نشست را پویش نمی‌کنند و حذف JSONLهای یتیم را پیشنهاد نمی‌دهند. فایل‌های رونوشت قدیمی فقط ورودی مهاجرت هستند و مرحلهٔ مهاجرت مالک واردکردن و حذف منبع است.
  • واردکردن رجیستری قدیمی sandbox زیر src/commands/doctor/legacy/sandbox-registry.ts قرار دارد؛ خواندن و نوشتن رجیستری فعال sandbox همچنان فقط از SQLite استفاده می‌کند.
  • تعمیر سلامت/واردکردن رونوشت قدیمی نشست زیر src/commands/doctor/legacy/session-transcript-health.ts قرار دارد؛ ماژول‌های فرمان زمان اجرا دیگر کد تجزیهٔ رونوشت JSONL یا تعمیر شاخهٔ فعال را در خود ندارند.

نکات برجستهٔ ادغام/حذف تکمیل‌شده:

  • وضعیت Plugin اکنون از پایگاه‌دادهٔ مشترک state/openclaw.sqlite استفاده می‌کند. واردکنندهٔ sidecar قدیمی و محلیِ شاخهٔ plugin-state/state.sqlite حذف شده است، زیرا آن چیدمان SQLite هرگز منتشر نشد. کمک‌تابع‌های کاوش/آزمایش، به‌جای افشای مسیر SQLite مختص وضعیت Plugin، databasePath مشترک را گزارش می‌کنند.
  • جدول‌های زمان اجرای وظیفه و Task Flow اکنون به‌جای tasks/runs.sqlite و tasks/flows/registry.sqlite در پایگاه‌دادهٔ مشترک state/openclaw.sqlite قرار دارند؛ واردکننده‌های sidecar قدیمی نیز به همان دلیل منتشرنشدن چیدمان حذف شده‌اند.
  • src/config/sessions/store.ts دیگر برای فرادادهٔ ورودی، به‌روزرسانی‌های مسیر یا خواندن زمان به‌روزرسانی به storePath نیاز ندارد. ماندگارسازی فرمان، پاک‌سازی نشست CLI، عمق زیرعامل، بازنویسی‌های احراز هویت و هویت نشست رونوشت از APIهای ردیف عامل/نشست استفاده می‌کنند. نوشتن‌ها به‌شکل وصله‌های ردیف SQLite همراه با تلاش مجدد در صورت تعارض خوش‌بینانه اعمال می‌شوند.
  • تفکیک مقصد نشست اکنون مقصدهای پایگاه‌دادهٔ هر عامل را ارائه می‌کند، نه مسیرهای قدیمی sessions.json. Gateway مشترک، فرادادهٔ ACP، ترمیم مسیر doctor و openclaw sessions، agent_databases را به‌همراه عامل‌های پیکربندی‌شده فهرست می‌کنند.
  • مسیریابی نشست Gateway اکنون از resolveGatewaySessionDatabaseTarget استفاده می‌کند؛ مقصد بازگردانده‌شده، به‌جای مسیر فایل ذخیره‌گاه نشست قدیمی، databasePath و کلیدهای ردیف SQLite نامزد را در بر دارد.
  • نوع‌های زمان اجرای نشست کانال اکنون {agentId, sessionKey} را برای خواندن زمان به‌روزرسانی، فرادادهٔ ورودی و به‌روزرسانی‌های آخرین مسیر ارائه می‌کنند. نوع سازگاری قدیمی saveSessionStore(storePath, store) حذف شده است.
  • سطوح نشستِ زمان اجرای Plugin، API افزونه و SDKِ Plugin اکنون به‌جای کمک‌تابع‌های سازگاریِ کل ذخیره‌گاه/فایل نشست فعال، کمک‌تابع‌های ردیف نشست مبتنی بر SQLite را ارائه می‌کنند. خروجی‌های سازگاری کتابخانهٔ ریشه فقط بیرون از SDKِ Plugin برای فراخواننده‌های داخلی قدیمی و مهاجرت همچنان در دسترس‌اند. کمک‌تابع قدیمی resolveLegacySessionStorePath حذف شده است؛ ساخت مسیر قدیمی sessions.json اکنون به fixtureهای مهاجرت و آزمایش محدود است.
  • src/config/sessions/session-entries.sqlite.ts اکنون ورودی‌های متعارف نشست را در پایگاه‌دادهٔ هر عامل ذخیره می‌کند و از وصلهٔ خواندن/درج یا به‌روزرسانی/حذف در سطح ردیف پشتیبانی می‌کند. درج یا به‌روزرسانی/وصله/حذف زمان اجرا دیگر گونه‌های مختلف حروف را پویش نمی‌کند یا کلیدهای نام مستعار قدیمی را نمی‌پیراید؛ متعارف‌سازی بر عهدهٔ doctor است. کمک‌تابع مستقل واردکردن JSON حذف شده است و مهاجرت، به‌جای جایگزینی کل جدول نشست، ردیف‌های جدیدتر را درج یا به‌روزرسانی و ادغام می‌کند. کمک‌تابع‌های عمومی خواندن/فهرست‌کردن/بارگذاری، فرادادهٔ پرتکرار نشست را از ردیف‌های نوع‌دار sessions و conversations نگاشت می‌کنند؛ entry_json یک سایهٔ سازگاری/اشکال‌زدایی است و می‌تواند بدون از دست رفتن هویت نوع‌دار نشست یا زمینهٔ تحویل، کهنه یا نامعتبر باشد.
  • src/config/sessions/delivery-info.ts اکنون زمینهٔ تحویل را از ردیف‌های نوع‌دارِ هر عامل sessions + conversations + session_conversations تفکیک می‌کند. این بخش دیگر هویت تحویل زمان اجرا را از session_entries.entry_json بازسازی نمی‌کند؛ نبود ردیف نوع‌دار مکالمه، مسئلهٔ مهاجرت/ترمیم doctor است، نه یک fallback زمان اجرا.
  • تصمیم‌های بازنشانی نشست ذخیره‌شده اکنون فرادادهٔ نوع‌دار sessions.session_scope، sessions.chat_type و sessions.channel را ترجیح می‌دهند. تجزیهٔ sessionKey فقط برای پسوندهای صریح رشته/موضوع در مقصدهای فرمان باقی مانده است؛ طبقه‌بندی بازنشانی گروهی در برابر مستقیم دیگر از شکل کلید به‌دست نمی‌آید.
  • طبقه‌بندی نمایش فهرست/وضعیت نشست اکنون از فرادادهٔ نوع‌دار چت و نوع نشست Gateway استفاده می‌کند. این بخش دیگر زیررشته‌های :group: یا :channel: درون session_key را حقیقت ماندگار گروهی/مستقیم تلقی نمی‌کند.
  • انتخاب خط‌مشی پاسخ بی‌صدا اکنون فقط از نوع صریح مکالمه یا فرادادهٔ سطح استفاده می‌کند. این بخش دیگر خط‌مشی مستقیم/گروهی را از زیررشته‌های session_key حدس نمی‌زند.
  • تفکیک مدل نمایش نشست اکنون شناسهٔ عامل را از مقصد پایگاه‌دادهٔ SQLite نشست دریافت می‌کند، نه با جداکردن آن از session_key.
  • آماده‌سازی مقصد اعلان عامل‌به‌عامل اکنون فقط از sessions.list deliveryContext نوع‌دار استفاده می‌کند. این بخش دیگر مسیریابی کانال/حساب/رشته را از origin قدیمی، فیلدهای آینه‌شدهٔ last* یا شکل session_key بازیابی نمی‌کند.
  • رد مقصد رشته توسط sessions_send اکنون فرادادهٔ مسیریابی نوع‌دار SQLite را می‌خواند. این بخش دیگر با تجزیهٔ پسوندهای رشته از کلید مقصد، مقصدها را رد یا قبول نمی‌کند.
  • اعتبارسنجی خط‌مشی ابزار با دامنهٔ گروه اکنون مسیریابی نوع‌دار مکالمهٔ SQLite را برای نشست فعلی یا ایجادشده می‌خواند. این بخش دیگر با رمزگشایی sessionKey به هویت گروه/کانال اعتماد نمی‌کند؛ وقتی هیچ ردیف نوع‌دار نشستی آن‌ها را تأیید نکند، شناسه‌های گروه ارائه‌شده توسط فراخواننده کنار گذاشته می‌شوند.
  • تطبیق بازنویسی مدل کانال اکنون از فرادادهٔ صریح مکالمهٔ گروه و والد استفاده می‌کند. این بخش دیگر شناسه‌های مکالمهٔ والد را از parentSessionKey رمزگشایی نمی‌کند.
  • وراثت بازنویسی مدل ذخیره‌شده اکنون به یک کلید صریح نشست والد از زمینهٔ نوع‌دار نشست نیاز دارد. این بخش دیگر بازنویسی‌های والد را از پسوندهای :thread: یا :topic: در sessionKey استخراج نمی‌کند.
  • پوشش قدیمی اطلاعات رشتهٔ نشست و تجزیه‌گر رشتهٔ Plugin بارگذاری‌شده حذف شده‌اند؛ هیچ کد زمان اجرایی config/sessions/thread-info را وارد نمی‌کند.
  • کمک‌تابع مکالمهٔ کانال دیگر پل‌های تجزیهٔ کلید کامل نشست را ارائه نمی‌کند. هسته همچنان شناسه‌های خام مکالمهٔ تحت مالکیت ارائه‌دهنده را از طریق resolveSessionConversation(...) نرمال‌سازی می‌کند، اما واقعیت‌های مسیر را از sessionKey بازسازی نمی‌کند.
  • تحویل تکمیل، خط‌مشی ارسال و نگهداشت وظیفه دیگر نوع چت را از شکل session_key استخراج نمی‌کنند. تجزیه‌گر قدیمی کلید نوع چت حذف شده است؛ این مسیرها به فرادادهٔ نوع‌دار نشست، زمینهٔ نوع‌دار تحویل یا واژگان صریح مقصد تحویل نیاز دارند.
  • فهرست/وضعیت نشست، عیب‌یابی، اتصال حساب تأیید، پالایش Heartbeat در TUI و خلاصه‌های مصرف دیگر SessionEntry.origin را برای مسیریابی ارائه‌دهنده/حساب/رشته/نمایش استخراج نمی‌کنند. تنها خواندن‌های باقی‌ماندهٔ origin در زمان اجرا مربوط به مفاهیم غیرنشستی یا اشیای تحویل نوبت جاری‌اند.
  • جست‌وجوی مکالمهٔ بومی درخواست تأیید اکنون ردیف‌های نوع‌دار مسیریابی نشست هر عامل را می‌خواند. این بخش دیگر هویت مکالمهٔ کانال/گروه/رشته را از sessionKey تجزیه نمی‌کند؛ نبود فرادادهٔ نوع‌دار یک مسئلهٔ مهاجرت/ترمیم است.
  • محموله‌های رویداد تغییر نشست/چت/نشست Gateway دیگر سایه‌های مسیر SessionEntry.origin یا last* را بازتاب نمی‌دهند؛ کلاینت‌ها channel، chatType و deliveryContext نوع‌دار را دریافت می‌کنند.
  • تفکیک تحویل Heartbeat اکنون می‌تواند deliveryContext نوع‌دار SQLite را مستقیماً دریافت کند و زمان اجرای Heartbeat، به‌جای اتکا به سایه‌های سازگاری session_entries برای مسیریابی جاری، ردیف تحویل نشست هر عامل را ارسال می‌کند.
  • تفکیک مقصد تحویل عامل ایزولهٔ Cron نیز پیش از fallback به محمولهٔ ورودی سازگاری، مسیر جاری خود را از ردیف نوع‌دار تحویل نشست هر عامل آماده می‌کند.
  • تفکیک مبدأ اعلان زیرعامل اکنون زمینهٔ نوع‌دار تحویل نشست درخواست‌کننده را از طریق loadRequesterSessionEntry عبور می‌دهد و آن ردیف را بر سایه‌های سازگاری last*/deliveryContext ترجیح می‌دهد.
  • به‌روزرسانی‌های فرادادهٔ نشست ورودی اکنون ابتدا با ردیف نوع‌دار تحویل هر عامل ادغام می‌شوند؛ فیلدهای تحویل قدیمی SessionEntry فقط وقتی fallback هستند که هیچ ردیف نوع‌دار مکالمه‌ای وجود نداشته باشد.
  • استخراج تحویل راه‌اندازی مجدد/به‌روزرسانی اکنون اجازه می‌دهد threadId نوع‌دار تحویل SQLite بر قطعه‌های موضوع/رشتهٔ تجزیه‌شده از sessionKey اولویت داشته باشد؛ تجزیه فقط fallback کلیدهای قدیمی با شکل رشته است.
  • شناسه‌های کانال زمینهٔ عامل hook اکنون ابتدا هویت نوع‌دار مکالمهٔ SQLite و سپس فرادادهٔ صریح پیام را ترجیح می‌دهند. این بخش دیگر قطعه‌های ارائه‌دهنده/گروه/کانال را از sessionKey تجزیه نمی‌کند.
  • وراثت مسیر خارجی chat.send در Gateway اکنون به‌جای استنباط دامنهٔ کانال/مستقیم/گروه از قطعه‌های sessionKey، فرادادهٔ نوع‌دار مسیریابی نشست SQLite را می‌خواند. نشست‌های با دامنهٔ کانال فقط زمانی ارث‌بری می‌کنند که کانال و نوع چت نشست نوع‌دار با زمینهٔ تحویل ذخیره‌شده مطابقت داشته باشند؛ نشست‌های main مشترک قاعدهٔ سخت‌گیرانه‌تر CLI/نبود فرادادهٔ کلاینت خود را حفظ می‌کنند.
  • مسیریابی بیدارسازی و ادامهٔ نشانگر راه‌اندازی مجدد اکنون پیش از صف‌کردن بیدارسازی‌های Heartbeat یا ادامه‌های مسیریابی‌شدهٔ نوبت عامل، ردیف‌های نوع‌دار تحویل/مسیریابی SQLite را می‌خواند. این بخش دیگر زمینهٔ تحویل را از سایهٔ JSON ورودی نشست بازسازی نمی‌کند.
  • تفکیک زمینهٔ tools.effective در Gateway اکنون برای ورودی‌های ارائه‌دهنده، حساب، مقصد، رشته و حالت پاسخ، ردیف‌های نوع‌دار تحویل/مسیریابی SQLite را می‌خواند. این بخش دیگر آن فیلدهای پرتکرار مسیریابی را از سایه‌های مبدأ کهنهٔ session_entries.entry_json بازیابی نمی‌کند.
  • مسیریابی مشاورهٔ صوتی بی‌درنگ اکنون تحویل والد/تماس را از ردیف‌های نوع‌دار نشست SQLite هر عامل تفکیک می‌کند. این بخش هنگام انتخاب مسیر پیام عامل تعبیه‌شده دیگر به سایه‌های سازگاری SessionEntry.deliveryContext fallback نمی‌کند.
  • رلهٔ Heartbeat ایجاد ACP و مسیریابی جریان والد اکنون تحویل والد را از ردیف‌های نوع‌دار نشست SQLite می‌خوانند. آن‌ها دیگر زمینهٔ تحویل والد را از سایه‌های سازگاری ورودی نشست بازسازی نمی‌کنند.
  • حفظ مسیر تحویل نشست اکنون از فرادادهٔ نوع‌دار چت و ستون‌های ماندگار تحویل پیروی می‌کند. این بخش دیگر راهنمایی‌های کانال، نشانگرهای مستقیم/main یا شکل رشته را از sessionKey استخراج نمی‌کند؛ مسیرهای داخلی وب‌چت فقط زمانی یک مقصد خارجی را به ارث می‌برند که SQLite از قبل هویت نوع‌دار/ماندگار تحویل را برای نشست داشته باشد.
  • استخراج عمومی تحویل نشست اکنون فقط ردیف دقیق و نوع‌دار تحویل نشست SQLite را می‌خواند. این بخش دیگر پسوندهای رشته/موضوع را تجزیه نمی‌کند یا از یک کلید رشته‌مانند به کلید نشست پایه fallback نمی‌کند.
  • ارسال پاسخ، بازیابی نشانگر راه‌اندازی مجدد و مسیریابی مشاورهٔ صوتی بی‌درنگ اکنون از ردیف‌های دقیق و نوع‌دار نشست/مکالمهٔ SQLite برای مسیریابی رشته استفاده می‌کنند. آن‌ها دیگر با تجزیهٔ کلیدهای نشست رشته‌مانند، شناسه‌های رشته یا زمینهٔ تحویل نشست پایه را بازیابی نمی‌کنند.
  • محدودسازی تاریخچهٔ PI تعبیه‌شده اکنون از نگاشت نوع‌دار مسیریابی نشست SQLite (sessions + conversations اصلی) برای ارائه‌دهنده، نوع چت و هویت همتا استفاده می‌کند. این بخش دیگر شکل ارائه‌دهنده، DM، گروه یا رشته را از sessionKey تجزیه نمی‌کند.
  • استنباط تحویل ابزار Cron اکنون فقط از تحویل صریح یا زمینهٔ نوع‌دار تحویل جاری استفاده می‌کند. این بخش دیگر مقصدهای کانال، همتا، حساب یا رشته را از agentSessionKey رمزگشایی نمی‌کند.
  • ردیف‌های نشست زمان اجرا دیگر نام مستعار مسیر قدیمی lastProvider را ندارند. کمک‌تابع‌ها و آزمایش‌ها از فیلدهای نوع‌دار lastChannel و deliveryContext استفاده می‌کنند؛ مهاجرت doctor تنها جایی است که باید نام‌های مستعار مسیر قدیمی‌تر یا سایه‌های ماندگار origin را تبدیل کند.
  • رویدادهای رونوشت، ردیف‌های VFS و ردیف‌های مصنوع ابزار اکنون در پایگاه‌دادهٔ هر عامل نوشته می‌شوند. جدول نگاشت جهانی و منتشرنشدهٔ فایل رونوشت حذف شده است؛ doctor در عوض مسیرهای منبع قدیمی را در ردیف‌های ماندگار مهاجرت ثبت می‌کند.
  • جست‌وجوی رونوشت زمان اجرا دیگر آفست‌های بایتی JSONL را پویش یا فایل‌های رونوشت قدیمی را کاوش نمی‌کند. مسیرهای چت/رسانه/تاریخچهٔ Gateway ردیف‌های رونوشت را از SQLite می‌خوانند؛ JSONL نشست اکنون فقط ورودی قدیمی doctor است، نه حالت زمان اجرا یا قالب خروجی.
  • روابط والد و شاخهٔ رونوشت از فرادادهٔ ساخت‌یافتهٔ parentTranscriptScope: {agentId, sessionId} در سرآیندهای رونوشت SQLite استفاده می‌کنند، نه رشته‌های مکان‌یاب مسیرمانند agent-db:...transcript_events....
  • قرارداد مدیر رونوشت دیگر سازنده‌های ماندگار ضمنی create(cwd) یا continueRecent(cwd) را ارائه نمی‌کند. مدیران رونوشت ماندگار با دامنهٔ صریح {agentId, sessionId} باز می‌شوند؛ فقط مدیرهای درون‌حافظه‌ای برای آزمون‌ها و تبدیل‌های خالص رونوشت، همچنان بدون دامنه باقی می‌مانند.
  • APIهای ذخیره‌گاه رونوشت زمان اجرا، دامنه SQLite را تفکیک می‌کنند، نه مسیرهای سیستم فایل را. راهنمای قدیمی resolve...ForPath و گزینه‌های نوشتن بلااستفاده transcriptPath از فراخوانندگان زمان اجرا حذف شده‌اند.
  • تفکیک نشست در زمان اجرا اکنون از {agentId, sessionId} استفاده می‌کند و نباید رشته‌های sqlite-transcript://<agent>/<session> را برای مرزهای خارجی مشتق کند. مسیرهای مطلق JSONL قدیمی فقط ورودی‌های مهاجرت doctor هستند.
  • رکوردهای پل مستقیم رله قلاب بومی اکنون در ردیف‌های مشترک نوع‌دار native_hook_relay_bridges قرار دارند که با شناسه رله کلیدگذاری شده‌اند. زمان اجرا دیگر برای این رکوردهای کوتاه‌عمر پل، رجیستری JSON با نام /tmp یا رکوردهای عمومی مبهم نمی‌نویسد.
  • runEmbeddedPiAgent(...) دیگر پارامتر مکان‌یاب رونوشت ندارد. توصیفگرهای آماده‌شده worker نیز مکان‌یاب‌های رونوشت را حذف کرده‌اند. وضعیت نشست زمان اجرا و اجراهای پیگیری صف‌شده، به‌جای دستگیره‌های مشتق‌شده رونوشت، {agentId, sessionId} را حمل می‌کنند.
  • Compaction تعبیه‌شده اکنون دامنه SQLite را از agentId و sessionId می‌گیرد. قلاب‌های Compaction، فراخوانی‌های موتور زمینه، واگذاری CLI و پاسخ‌های پروتکل نباید دستگیره‌های مشتق‌شده sqlite-transcript://... را دریافت کنند. کد صدور/اشکال‌زدایی می‌تواند مصنوعات صریح کاربر را از ردیف‌ها ایجاد کند، اما مسیر عمومی صدور JSONL نشست ارائه نمی‌کند و نام فایل‌ها را دوباره وارد هویت زمان اجرا نمی‌کند.
  • /export-session ردیف‌های رونوشت را از SQLite می‌خواند و فقط نمای مستقل HTML درخواست‌شده را می‌نویسد. نمایشگر تعبیه‌شده دیگر JSONL نشست را از آن ردیف‌ها بازسازی یا بارگیری نمی‌کند.
  • واگذاری موتور زمینه دیگر مکان‌یاب رونوشت را برای بازیابی هویت عامل تجزیه نمی‌کند. زمینه آماده‌شده زمان اجرا، agentId تفکیک‌شده را به آداپتور داخلی Compaction منتقل می‌کند.
  • بازنویسی رونوشت و کوتاه‌سازی زنده نتیجه ابزار اکنون وضعیت رونوشت را بر اساس {agentId, sessionId} می‌خوانند و ماندگار می‌کنند و برای payloadهای رویداد به‌روزرسانی رونوشت، مکان‌یاب‌های موقت مشتق نمی‌کنند.
  • سطح راهنمای وضعیت رونوشت دیگر گونه‌های مبتنی بر مکان‌یاب readTranscriptState، replaceTranscriptStateEvents یا persistTranscriptStateMutation را ندارد. فراخوانندگان زمان اجرا باید از APIهای {agentId, sessionId} استفاده کنند. واردسازی doctor فایل‌های قدیمی را با مسیر صریح فایل می‌خواند و ردیف‌های SQLite را می‌نویسد؛ رشته‌های مکان‌یاب را مهاجرت نمی‌دهد.
  • قرارداد مدیر نشست زمان اجرا دیگر open(locator)، forkFrom(locator) یا setTranscriptLocator(...) را در معرض نمی‌گذارد. مدیرهای نشست ماندگار فقط بر اساس {agentId, sessionId} باز می‌شوند؛ راهنماهای فهرست/انشعاب به‌جای نمای مدیر رونوشت، روی APIهای ردیف‌محور نشست و نقطه‌بررسی قرار دارند.
  • APIهای خواننده رونوشت Gateway دامنه‌محور هستند. آن‌ها {agentId, sessionId} را می‌گیرند و مکان‌یاب موقعیتی رونوشت را که ممکن است تصادفاً به هویت زمان اجرا تبدیل شود، نمی‌پذیرند. تجزیه مکان‌یاب رونوشت فعال حذف شده است؛ مسیرهای منبع قدیمی فقط توسط کد واردسازی doctor خوانده می‌شوند.
  • رویدادهای به‌روزرسانی رونوشت نیز دامنه‌محور هستند. emitSessionTranscriptUpdate دیگر رشته مکان‌یاب بدون پوشش را نمی‌پذیرد و شنونده‌ها بدون تجزیه دستگیره، بر اساس {agentId, sessionId} مسیریابی می‌کنند.
  • پخش پیام نشست Gateway کلیدهای نشست را از دامنه عامل/نشست تفکیک می‌کند، نه از مکان‌یاب رونوشت. تفکیک‌گر/کش قدیمی تبدیل مکان‌یاب رونوشت به کلید نشست حذف شده است.
  • فیلترهای SSE تاریخچه نشست Gateway، به‌روزرسانی‌های زنده را بر اساس دامنه عامل/نشست فیلتر می‌کنند. دیگر برای تصمیم‌گیری درباره اینکه آیا یک جریان باید به‌روزرسانی را دریافت کند، گزینه‌های مکان‌یاب رونوشت، مسیرهای واقعی یا هویت‌های فایل‌مانند رونوشت را متعارف‌سازی نمی‌کند.
  • قلاب‌های چرخه عمر نشست دیگر مکان‌یاب‌های رونوشت را روی session_end مشتق یا در معرض نمی‌گذارند. مصرف‌کنندگان قلاب، sessionId، sessionKey، شناسه‌های نشست بعدی و زمینه عامل را دریافت می‌کنند؛ فایل‌های رونوشت بخشی از قرارداد چرخه عمر نیستند.
  • قلاب‌های بازنشانی نیز دیگر مکان‌یاب‌های رونوشت را مشتق یا در معرض نمی‌گذارند. payload مربوط به before_reset، پیام‌های بازیابی‌شده SQLite را همراه با دلیل بازنشانی حمل می‌کند، درحالی‌که هویت نشست در زمینه قلاب باقی می‌ماند.
  • بازنشانی مهار عامل دیگر مکان‌یاب رونوشت را نمی‌پذیرد. ارسال بازنشانی با sessionId/sessionKey به‌همراه دلیل دامنه‌بندی می‌شود.
  • نوع‌های نشست افزونه عامل دیگر transcriptLocator را در معرض نمی‌گذارند؛ افزونه‌ها باید به‌جای دسترسی به هویت فایل‌مانند رونوشت، از زمینه نشست و APIهای زمان اجرا استفاده کنند.
  • قلاب‌های Compaction مربوط به Plugin دیگر مکان‌یاب‌های رونوشت را در معرض نمی‌گذارند. زمینه قلاب از قبل هویت نشست را حمل می‌کند و خواندن رونوشت باید به‌جای دستگیره‌های فایل‌مانند، از APIهای آگاه از دامنه SQLite عبور کند.
  • قلاب‌های before_agent_finalize دیگر transcriptPath را، از جمله در payloadهای رله قلاب بومی، در معرض نمی‌گذارند. قلاب‌های نهایی‌سازی فقط از زمینه نشست استفاده می‌کنند.
  • پاسخ‌های بازنشانی Gateway دیگر روی ورودی بازگشتی مکان‌یاب رونوشت نمی‌سازند. بازنشانی، ردیف‌های رونوشت SQLite را ایجاد می‌کند، ورودی پاک نشست را بازمی‌گرداند و دسترسی به رونوشت را به خواننده‌های آگاه از دامنه واگذار می‌کند.
  • نتایج اجرای تعبیه‌شده و Compaction دیگر مکان‌یاب‌های رونوشت را برای حسابداری نشست نمایش نمی‌دهند. Compaction خودکار فقط sessionId فعال، شمارنده‌های Compaction و فراداده توکن را به‌روزرسانی می‌کند.
  • نتایج تلاش تعبیه‌شده دیگر transcriptLocatorUsed را بازنمی‌گردانند و نتایج compact() موتور زمینه نیز دیگر مکان‌یاب‌های رونوشت را بازنمی‌گردانند. حلقه‌های تلاش مجدد زمان اجرا فقط sessionId جانشین را می‌پذیرند.
  • نتایج افزودن رونوشت آینه تحویل دیگر مکان‌یاب‌های رونوشت را بازنمی‌گردانند. فراخوانندگان messageId افزوده‌شده را دریافت می‌کنند؛ سیگنال‌های به‌روزرسانی رونوشت از دامنه SQLite استفاده می‌کنند.
  • راهنماهای انشعاب نشست والد فقط sessionId انشعاب‌یافته را بازمی‌گردانند. آماده‌سازی زیرعامل، دامنه عامل/نشست فرزند را به موتورها می‌فرستد.
  • پارامترهای اجراکننده CLI و بذرگذاری مجدد تاریخچه دیگر مکان‌یاب‌های رونوشت را نمی‌پذیرند. خواندن تاریخچه CLI دامنه رونوشت SQLite را از {agentId, sessionId} و زمینه کلید نشست تفکیک می‌کند.
  • فیکسچرهای آزمون CLI و اجراکننده تعبیه‌شده اکنون به‌جای وانمودکردن اینکه نشست‌های فعال فایل‌های *.jsonl هستند یا عبور دادن رشته sqlite-transcript://... از پارامترهای زمان اجرا، ردیف‌های رونوشت SQLite را بر اساس شناسه نشست بذرگذاری و می‌خوانند.
  • رویدادهای محافظ نتیجه ابزار نشست حتی وقتی مدیر درون‌حافظه‌ای مکان‌یاب مشتق‌شده‌ای ندارد، از دامنه شناخته‌شده نشست منتشر می‌شوند. آزمون‌های آن دیگر فایل‌های فعال رونوشت /tmp/*.jsonl را جعل نمی‌کنند.
  • راهنماهای BTW و نقطه‌بررسی Compaction اکنون ردیف‌های رونوشت را بر اساس دامنه SQLite می‌خوانند و منشعب می‌کنند. فراداده نقطه‌بررسی اکنون فقط شناسه‌های نشست و شناسه‌های برگ/ورودی را ذخیره می‌کند؛ مکان‌یاب‌های مشتق‌شده دیگر در payloadهای نقطه‌بررسی نوشته نمی‌شوند.
  • جست‌وجوی کلید رونوشت Gateway در مرزهای پروتکل از دامنه رونوشت SQLite استفاده می‌کند و دیگر مسیر واقعی یا آمار نام فایل‌های رونوشت را نمی‌گیرد.
  • چرخش رونوشت Compaction خودکار، ردیف‌های جانشین رونوشت را مستقیماً از طریق ذخیره‌گاه رونوشت SQLite می‌نویسد. ردیف‌های نشست فقط هویت نشست جانشین را نگه می‌دارند، نه مسیر پایدار JSONL یا مکان‌یاب ماندگار را.
  • Compaction تعبیه‌شده موتور زمینه از راهنماهای چرخش رونوشت نام‌گذاری‌شده با SQLite استفاده می‌کند. آزمون‌های چرخش دیگر مسیرهای جانشین JSONL را نمی‌سازند یا نشست‌های فعال را به‌صورت فایل مدل نمی‌کنند.
  • نگهداشت تصویر خروجی مدیریت‌شده، کش پیام رونوشت خود را به‌جای فراخوانی‌های آمار سیستم فایل، از آمار رونوشت SQLite کلیدگذاری می‌کند.
  • قفل‌های نشست زمان اجرا و مسیر مستقل doctor قدیمی .jsonl.lock حذف شده‌اند.
  • بارل زمان اجرای Microsoft Teams و SDK عمومی Plugin دیگر راهنمای قدیمی قفل فایل را بازصادر نمی‌کنند؛ مسیرهای وضعیت پایدار Plugin بر SQLite متکی هستند.
  • هرس بر اساس سن/تعداد نشست و پاک‌سازی صریح نشست حذف شده‌اند. doctor مالک واردسازی قدیمی است؛ نشست‌های کهنه صریحاً بازنشانی یا حذف می‌شوند.
  • بررسی‌های یکپارچگی doctor دیگر فایل JSONL قدیمی را به‌عنوان رونوشت فعال معتبر برای ردیف نشست SQLite حساب نمی‌کنند. سلامت رونوشت فعال فقط بر SQLite متکی است؛ فایل‌های JSONL قدیمی به‌عنوان ورودی‌های مهاجرت/پاک‌سازی یتیم گزارش می‌شوند.
  • doctor دیگر agents/<agent>/sessions/ را وضعیت الزامی زمان اجرا در نظر نمی‌گیرد. فقط زمانی آن دایرکتوری را اسکن می‌کند که از قبل وجود داشته باشد، آن‌هم به‌عنوان ورودی واردسازی قدیمی یا پاک‌سازی یتیم.
  • sessions.resolve در Gateway، مسیرهای وصله/بازنشانی/فشرده‌سازی نشست، ایجاد زیرعامل، توقف سریع، فراداده ACP، نشست‌های ایزوله‌شده Heartbeat و وصله‌کردن TUI دیگر کلیدهای قدیمی نشست را به‌عنوان اثر جانبی کار عادی زمان اجرا مهاجرت یا هرس نمی‌کنند.
  • تفکیک نشست فرمان CLI اکنون به‌جای storePath، agentId مالک را بازمی‌گرداند و دیگر هنگام تفکیک عادی --to یا --session-id، ردیف‌های قدیمی نشست اصلی را کپی نمی‌کند. متعارف‌سازی ردیف اصلی قدیمی فقط به doctor تعلق دارد.
  • تفکیک عمق زیرعامل در زمان اجرا دیگر sessions.json یا ذخیره‌گاه‌های نشست JSON5 را نمی‌خواند. ردیف‌های SQLite با نام session_entries را بر اساس شناسه عامل می‌خواند و فراداده قدیمی عمق/نشست فقط می‌تواند از مسیر واردسازی doctor وارد شود.
  • نادیده‌گیری‌های نشست نمایه احراز هویت، به‌جای بارگذاری تنبل زمان اجرای ذخیره‌گاه نشست فایل‌مانند، از طریق upsert مستقیم ردیف {agentId, sessionKey} ماندگار می‌شوند.
  • دروازه‌گذاری پرگویی پاسخ خودکار و راهنماهای به‌روزرسانی نشست اکنون ردیف‌های نشست SQLite را بر اساس هویت نشست می‌خوانند/upsert می‌کنند و دیگر پیش از دست‌زدن به وضعیت ماندگار ردیف، به مسیر ذخیره‌گاه قدیمی نیاز ندارند.
  • راهنماهای فراداده نشست اجرای فرمان اکنون از نام‌ها و مسیرهای ماژول ورودی‌محور استفاده می‌کنند؛ سطح راهنمای فرمان قدیمی session-store حذف شده است.
  • بذرگذاری سرآیند راه‌اندازی و سخت‌سازی مرز Compaction دستی اکنون مستقیماً ردیف‌های رونوشت SQLite را تغییر می‌دهند. فراخوانندگان زمان اجرا هویت نشست را می‌فرستند، نه مسیرهای قابل‌نوشتن .jsonl را.
  • بازپخش بی‌صدای چرخش نشست، نوبت‌های اخیر کاربر/دستیار را بر اساس {agentId, sessionId} از ردیف‌های رونوشت SQLite کپی می‌کند. دیگر مکان‌یاب‌های رونوشت مبدأ یا مقصد را نمی‌پذیرد.
  • ردیف‌های تازه نشست زمان اجرا دیگر مکان‌یاب‌های رونوشت را ذخیره نمی‌کنند. فراخوانندگان مستقیماً از {agentId, sessionId} استفاده می‌کنند؛ فرمان‌های صدور/اشکال‌زدایی هنگام ایجاد ردیف‌ها می‌توانند نام فایل خروجی را انتخاب کنند.
  • شروع نشست جدید رونوشت ماندگار اکنون همیشه ردیف‌های SQLite را بر اساس دامنه باز می‌کند. مدیر نشست دیگر مسیر یا مکان‌یاب رونوشت قبلی مربوط به دوره فایل را به‌عنوان هویت نشست جدید دوباره استفاده نمی‌کند.
  • نشست‌های رونوشت ماندگار از API صریح openTranscriptSessionManagerForSession({agentId, sessionId}) استفاده می‌کنند. نماهای ایستای قدیمی SessionManager.create/openForSession/list/forkFromSession حذف شده‌اند تا آزمون‌ها و کد زمان اجرا نتوانند تصادفاً کشف نشست مربوط به دوره فایل را دوباره ایجاد کنند.
  • زمان اجرای Plugin دیگر api.runtime.agent.session.resolveTranscriptLocatorPath را در معرض نمی‌گذارد؛ کد Plugin از راهنماهای ردیف SQLite و مقادیر دامنه استفاده می‌کند.
  • سطح SDK عمومی session-store-runtime اکنون فقط راهنماهای ردیف نشست و ردیف رونوشت را صادر می‌کند. راهنماهای متمرکز طرح‌واره/مسیر/تراکنش SQLite در sqlite-runtime قرار دارند؛ راهنماهای خام بازکردن/بستن/بازنشانی فقط برای آزمون‌های داخلی محلی باقی می‌مانند.
  • طبقه‌بندهای قدیمی نام فایل مسیر/نقطه‌بررسی .jsonl اکنون در ماژول فایل نشست قدیمی doctor قرار دارند. اعتبارسنجی نشست هسته دیگر راهنماهای مصنوعات فایل را برای تصمیم‌گیری درباره شناسه‌های عادی نشست SQLite وارد نمی‌کند.
  • اجراهای زیرعامل مسدودکننده Active Memory به‌جای ایجاد فایل‌های موقت یا ماندگار session.jsonl زیر وضعیت Plugin، از ردیف‌های رونوشت SQLite استفاده می‌کنند. گزینه قدیمی transcriptDir حذف شده است.
  • تولید یک‌باره slug و اجراهای برنامه‌ریز عامل سیستم به‌جای ایجاد فایل‌های موقت session.jsonl، از ردیف‌های رونوشت SQLite استفاده می‌کنند.
  • llm-task اجراهای کمکی و استخراج تعهدات پنهان نیز از ردیف‌های رونوشت SQLite استفاده می‌کنند؛ بنابراین این نشست‌های کمکیِ مختص مدل دیگر فایل‌های موقت رونوشت JSON/JSONL ایجاد نمی‌کنند.
  • TranscriptSessionManager اکنون فقط یک محدوده بازشده رونوشت SQLite است. کد زمان اجرا آن را با openTranscriptSessionManagerForSession({agentId, sessionId}) باز می‌کند؛ جریان‌های ایجاد، شاخه‌سازی، ادامه، فهرست‌کردن و انشعاب، به‌جای نماهای ایستای مدیر، در کمک‌کننده‌های ردیف SQLite متعلق به خود قرار دارند. کد doctor/import/debug فایل‌های منبع قدیمیِ صریح را خارج از مدیر نشست زمان اجرا مدیریت می‌کند.
  • متدهای نمای منسوخ SessionManager.newSession() و SessionManager.createBranchedSession() حذف شدند. نشست‌های جدید و نوادگان رونوشت به‌جای تبدیل یک مدیر ازپیش‌بازشده به نشستی پایدار و متفاوت، به‌وسیله گردش‌کار SQLite متعلق به خود ایجاد می‌شوند.
  • تصمیم‌های انشعاب رونوشت والد و ایجاد انشعاب دیگر storePath یا sessionsDir را نمی‌پذیرند؛ آن‌ها به‌جای فراداده مسیر سیستم فایل نگه‌داری‌شده، از محدوده رونوشت SQLiteِ {agentId, sessionId} استفاده می‌کنند.
  • Memory-host دیگر کمک‌کننده‌های بی‌عملِ طبقه‌بندی رونوشتِ پوشه نشست را صادر نمی‌کند؛ پالایش رونوشت اکنون هنگام ساخت ورودی از فراداده ردیف SQLite مشتق می‌شود.
  • آزمون‌های برون‌بری نشست Memory-host و QMD از محدوده‌های رونوشت SQLite استفاده می‌کنند. مسیرهای قدیمی agents/<agentId>/sessions/*.jsonl فقط در مواردی پوشش داده می‌شوند که آزمونی عمداً سازگاری doctor/import/export را اثبات می‌کند.
  • بازرسی خام نشست در QA-lab اکنون به‌جای خواندن agents/qa/sessions/sessions.json، از طریق Gateway از sessions.list استفاده می‌کند؛ بازخورد MSteams مستقیماً و بدون ساختن مسیر JSONL جعلی به رونوشت‌های SQLite افزوده می‌شود.
  • نوبت‌های ورودی مشترک کانال اکنون به‌جای storePath قدیمی، {agentId, sessionKey} را حمل می‌کنند. مسیرهای ثبت 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 اکنون فراداده زمان به‌روزرسانی را می‌خوانند و ردیف‌های نشست ورودی را از طریق هویت SQLite ثبت می‌کنند.
  • ماندگاری مکان‌یاب رونوشت از ردیف‌های نشست فعال حذف شده است. resolveSessionTranscriptTarget، agentId، sessionId و فراداده اختیاری موضوع را برمی‌گرداند؛ doctor تنها کدی است که نام فایل‌های رونوشت قدیمی را وارد می‌کند.
  • سرآیندهای رونوشت زمان اجرا از نسخه SQLiteِ 1 آغاز می‌شوند. ارتقای قالب‌های قدیمی JSONL V1/V2/V3 فقط در واردسازی doctor قرار دارد و پیش از ذخیره ردیف‌ها، سرآیندهای واردشده را به نسخه فعلی رونوشت SQLite عادی‌سازی می‌کند.
  • محافظ database-first اکنون SessionManager.listAll و SessionManager.forkFromSession را ممنوع می‌کند؛ فهرست‌کردن نشست و گردش‌کارهای انشعاب/بازیابی باید روی APIهای ردیفی/محدوده‌دار SQLite باقی بمانند.
  • این محافظ همچنین نام کمک‌کننده‌های قدیمیِ تجزیه JSONL رونوشت/ترمیم شاخه فعال را خارج از کد doctor/import ممنوع می‌کند تا زمان اجرا نتواند مسیر مهاجرت قدیمی دیگری برای رونوشت ایجاد کند.
  • اجراهای توکار PI دستگیره‌های ورودی رونوشت را رد می‌کنند. آن‌ها پیش از راه‌اندازی worker و دوباره پیش از دسترسی تلاش به وضعیت رونوشت، از هویت SQLiteِ {agentId, sessionId} استفاده می‌کنند. ورودی منسوخ /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 اکنون به‌جای فیلد فایل‌مانند قدیمی storePath، مقدار storeKey را گزارش می‌کند.
  • بارگذاری و زمان‌بندی زمان اجرای Cron دیگر قالب‌های قدیمی کار پایدارشده مانند jobId، schedule.cron، مقدار عددی atMs، بولی‌های رشته‌ای یا نبود sessionTarget را عادی‌سازی نمی‌کند. واردسازی قدیمی doctor پیش از درج ردیف‌ها در SQLite مالک این ترمیم‌هاست.
  • ایجاد ACP دیگر مسیرهای فایل JSONL رونوشت را تفکیک یا پایدار نمی‌کند. راه‌اندازی ایجاد و اتصال رشته، ردیف نشست SQLite را مستقیماً پایدار می‌کنند و شناسه نشست را به‌عنوان هویت نگه‌داری‌شده رونوشت حفظ می‌کنند.
  • APIهای فراداده نشست ACP اکنون ردیف‌های SQLite را بر اساس agentId می‌خوانند/فهرست می‌کنند/درج یا به‌روزرسانی می‌کنند و دیگر storePath را به‌عنوان بخشی از قرارداد ورودی نشست ACP ارائه نمی‌دهند.
  • محاسبه مصرف نشست و تجمیع مصرف Gateway اکنون رونوشت‌ها را فقط با {agentId, sessionId} تفکیک می‌کنند. کش هزینه/مصرف و خلاصه‌های نشست کشف‌شده دیگر رشته‌های مکان‌یاب رونوشت را نمی‌سازند یا برنمی‌گردانند.
  • افزودن گفت‌وگوی Gateway، ماندگاری بخش ناقص هنگام لغو، /sessions.send و نوشتن رسانه webchat در رونوشت، مستقیماً از طریق محدوده رونوشت SQLite داده می‌افزایند. کمک‌کننده تزریق رونوشت Gateway دیگر پارامتر transcriptLocator را نمی‌پذیرد.
  • کشف رونوشت SQLite اکنون فقط محدوده‌ها و آمار رونوشت را فهرست می‌کند: {agentId, sessionId, updatedAt, eventCount}. کمک‌کننده سازگاری بلااستفاده listSqliteSessionTranscriptLocators و فیلد هر ردیف locator حذف شده‌اند.
  • زمان اجرای ترمیم رونوشت اکنون فقط repairTranscriptSessionStateIfNeeded({agentId, sessionId}) را ارائه می‌کند. کمک‌کننده قدیمیِ ترمیم مبتنی بر مکان‌یاب حذف شده است؛ کد doctor/debug مسیرهای صریح فایل منبع را می‌خواند و هرگز رشته‌های مکان‌یاب را مهاجرت نمی‌دهد.
  • زمان اجرای دفتر بازپخش ACP اکنون به‌جای acp/event-ledger.json، ردیف‌های بازپخش هر نشست را در پایگاه‌داده مشترک وضعیت SQLite ذخیره می‌کند؛ doctor فایل قدیمی را وارد و حذف می‌کند.
  • کمک‌کننده‌های خواندن رونوشت Gateway اکنون به‌جای نام ماژول قدیمی session-utils.fs در src/gateway/session-transcript-readers.ts قرار دارند. بررسی تاریخچه تلاش دوباره در حالت fallback بر اساس محتوای رونوشت SQLite نام‌گذاری شده است، نه سطح قدیمی کمک‌کننده فایل.
  • کمک‌کننده‌های گفت‌وگوی تزریق‌شده و Compaction در Gateway اکنون به‌جای نامیدن مقادیر به‌صورت مسیرهای رونوشت یا فایل‌های منبع، محدوده رونوشت SQLite را از طریق APIهای کمک‌کننده داخلی عبور می‌دهند.
  • تشخیص ادامه bootstrap اکنون ردیف‌های رونوشت SQLite را از طریق hasCompletedBootstrapTranscriptTurn بررسی می‌کند؛ دیگر نامی فایل‌مانند برای کمک‌کننده ارائه نمی‌دهد.
  • آزمون‌های embedded-runner اکنون از هویت رونوشت SQLite استفاده می‌کنند و بازکردن مدیر رونوشت جدید همیشه به یک sessionId صریح نیاز دارد.
  • کمک‌کننده‌های نمایه‌سازی حافظه اکنون در سراسر مسیر از اصطلاحات رونوشت SQLite استفاده می‌کنند: میزبان listSessionTranscriptScopesForAgent و sessionTranscriptKeyForScope را صادر می‌کند، همگام‌سازی هدفمند sessionTranscripts را در صف قرار می‌دهد، نتایج عمومی جست‌وجوی نشست مسیرهای مبهم transcript:<agent>:<session> را ارائه می‌کنند و کلید منبع DB داخلی به‌جای مسیر فایل جعلی، session:<session> در source_kind='sessions' است.
  • کمک‌کننده عمومی حذف تکرار پایدار در SDKِ Plugin دیگر گزینه‌های فایل‌مانند ارائه نمی‌کند. فراخوان‌ها کلیدهای محدوده SQLite را فراهم می‌کنند و ردیف‌های پایدار حذف تکرار در وضعیت مشترک Plugin قرار می‌گیرند.
  • توکن‌های SSO در Microsoft Teams از فایل‌های JSON قفل‌شده به وضعیت Plugin در SQLite منتقل شدند. Doctor فایل msteams-sso-tokens.json را وارد می‌کند، کلیدهای متعارف توکن SSO را از محموله‌ها بازسازی می‌کند و فایل منبع را حذف می‌کند. توکن‌های OAuth واگذارشده در مرز خصوصی فایل اعتبارنامه موجود خود باقی می‌مانند.
  • وضعیت کش همگام‌سازی Matrix از bot-storage.json به وضعیت Plugin در SQLite منتقل شد. Doctor محموله‌های همگام‌سازی خام یا بسته‌بندی‌شده قدیمی را وارد می‌کند و فایل منبع را حذف می‌کند. کلاینت‌های فعال آداپتور Matrix و QA Lab Matrix یک پوشه ریشه مخزن همگام‌سازی SQLite را عبور می‌دهند، نه مسیر جعلی sync-store.json یا bot-storage.json.
  • وضعیت مهاجرت رمزنگاری قدیمی Matrix از legacy-crypto-migration.json به وضعیت Plugin در SQLite منتقل شد. Doctor فایل وضعیت قدیمی را وارد می‌کند؛ snapshotهای IndexedDB در SDKِ Matrix از crypto-idb-snapshot.json به blobهای Plugin در SQLite منتقل شدند. کلیدهای بازیابی و اعتبارنامه‌های Matrix ردیف‌های وضعیت Plugin در SQLite هستند؛ فایل‌های JSON قدیمی آن‌ها فقط ورودی‌های مهاجرت doctor هستند.
  • گزارش‌های فعالیت Memory Wiki اکنون به‌جای .openclaw-wiki/log.jsonl از وضعیت Plugin در SQLite استفاده می‌کنند. فراهم‌کننده مهاجرت Memory Wiki گزارش‌های JSONL قدیمی را وارد می‌کند؛ markdown ویکی و محتوای صندوق کاربر به‌عنوان محتوای فضای کاری، مبتنی بر فایل باقی می‌مانند.
  • Memory Wiki دیگر .openclaw-wiki/state.json یا پوشه استفاده‌نشده .openclaw-wiki/locks را ایجاد نمی‌کند. اگر صندوقی قدیمی هنوز آن‌ها را داشته باشد، فراهم‌کننده مهاجرت این فایل‌های بازنشسته فراداده Plugin را حذف می‌کند.
  • ورودی‌های ممیزی system-agent اکنون به‌جای audit/crestodian.jsonl از وضعیت Plugin هسته در SQLite استفاده می‌کنند. Doctor گزارش ممیزی JSONL قدیمی را وارد می‌کند و پس از واردسازی موفق آن را حذف می‌کند.
  • ورودی‌های ممیزی نوشتن/مشاهده پیکربندی اکنون به‌جای logs/config-audit.jsonl از وضعیت Plugin هسته در SQLite استفاده می‌کنند. Doctor گزارش ممیزی JSONL قدیمی را وارد می‌کند و پس از واردسازی موفق آن را حذف می‌کند.
  • همراه macOS هنگام ویرایش openclaw.json دیگر فایل‌های جانبی محلی برنامه logs/config-audit.jsonl یا logs/config-health.json را نمی‌نویسد. فایل پیکربندی همچنان مبتنی بر فایل باقی می‌ماند، snapshotهای بازیابی کنار فایل پیکربندی می‌مانند و وضعیت پایدار ممیزی/سلامت پیکربندی متعلق به مخزن SQLite در Gateway است.
  • تأییدهای در انتظار نجات system-agent اکنون به‌جای crestodian/rescue-pending/*.json یا openclaw/rescue-pending/*.json از وضعیت Plugin هسته در SQLite استفاده می‌کنند. این قابلیت‌های امنیتی کوتاه‌عمر هرگز وارد نمی‌شوند؛ doctor هر دو پوشه بازنشسته را دور می‌اندازد تا ارتقا نتواند نوشتن منسوخی را دوباره فعال کند.
  • وضعیت موقت فعال‌سازی Phone Control اکنون به‌جای plugins/phone-control/armed.json از وضعیت Plugin در SQLite استفاده می‌کند. Doctor فایل قدیمی وضعیت فعال‌شده را به فضای نام phone-control/arm-state وارد می‌کند و فایل را حذف می‌کند.
  • Doctor دیگر رونوشت‌های JSONL را درجا ترمیم نمی‌کند یا فایل‌های پشتیبان JSONL نمی‌سازد. شاخه فعال را به SQLite وارد می‌کند و منبع قدیمی را حذف می‌کند.
  • جست‌وجوی رونوشت در hook حافظه نشست از خواندن‌های SQLiteِ فقط‌محدوده {agentId, sessionId} استفاده می‌کند. کمک‌کننده آن دیگر مکان‌یاب‌های رونوشت، خواندن فایل قدیمی یا گزینه‌های بازنویسی فایل را نمی‌پذیرد یا مشتق نمی‌کند.
  • اتصال‌های گفت‌وگوی app-server در Codex اکنون وضعیت Plugin در SQLite را با کلید نشست OpenClaw یا محدوده صریح {agentId, sessionId} کلیدگذاری می‌کنند. آن‌ها نباید اتصال‌های fallback مسیر رونوشت را حفظ کنند.
  • خواندن تاریخچه آینه‌شده app-server در Codex فقط از محدوده رونوشت SQLite استفاده می‌کند؛ نباید هویت را از مسیر فایل رونوشت بازیابی کند.
  • مسیرهای ترتیب نقش و بازنشانی Compaction دیگر فایل‌های رونوشت قدیمی را حذف پیوند نمی‌کنند؛ بازنشانی فقط ردیف نشست SQLite و هویت رونوشت را می‌چرخاند.
  • پاسخ‌های بازنشانی و checkpoint در Gateway ردیف‌های پاک نشست را همراه شناسه‌های نشست برمی‌گردانند. دیگر مکان‌یاب‌های رونوشت SQLite را برای کلاینت‌ها نمی‌سازند.
  • Dreaming در memory-core دیگر با بررسی نبود فایل‌های JSONL ردیف‌های نشست را هرس نمی‌کند. پاک‌سازی subagent به‌جای بررسی وجود در سیستم فایل از طریق API زمان اجرای نشست انجام می‌شود. آزمون‌های ورود رونوشت آن به‌جای ایجاد fixtureهای agents/<id>/sessions یا جای‌بان‌های مکان‌یاب، ردیف‌های SQLite را مستقیماً مقداردهی اولیه می‌کنند.
  • نمایه‌سازی رونوشت حافظه ممکن است transcript:<agentId>:<sessionId> را به‌عنوان مسیر مجازی نتیجه جست‌وجو برای کمک‌کننده‌های ارجاع/خواندن ارائه کند. منبع پایدار نمایه رابطه‌ای است (source_kind='sessions'، source_key='session:<sessionId>'، session_id=<sessionId>)، بنابراین این مقدار نه مکان‌یاب رونوشت زمان اجرا است، نه مسیر سیستم فایل، و هرگز نباید دوباره به APIهای زمان اجرای نشست ارسال شود.
  • وضعیت حافظه در doctor مربوط به Gateway، شمارش‌های یادآوری کوتاه‌مدت و سیگنال فاز را به‌جای memory/.dreams/*.json از ردیف‌های وضعیت Plugin در SQLite می‌خواند؛ خروجی CLI و doctor اکنون آن فضای ذخیره‌سازی را یک مخزن SQLite می‌نامند، نه یک مسیر.
  • زمان اجرای هسته حافظه، وضعیت CLI، متدهای doctor مربوط به Gateway و نماهای SDK افزونه دیگر فایل‌های قدیمی .dreams/session-corpus را ممیزی یا بایگانی نمی‌کنند. این فایل‌ها فقط ورودی مهاجرت هستند؛ doctor آن‌ها را به SQLite وارد می‌کند و پس از راستی‌آزمایی، منبع را حذف می‌کند. ردیف‌های شواهد دریافت نشست فعال اکنون از مسیر مجازی SQLite یعنی memory/session-ingestion/<day>.txt استفاده می‌کنند؛ زمان اجرا هرگز وضعیت را در .dreams/session-corpus نمی‌نویسد یا از آن استخراج نمی‌کند.
  • مصنوعات عمومی هسته حافظه، رویدادهای میزبان SQLite را به‌صورت مصنوع JSON مجازی memory/events/memory-host-events.json ارائه می‌کنند؛ آن‌ها دیگر از مسیر منبع قدیمی .dreams/events.jsonl استفاده مجدد نمی‌کنند.
  • رجیستری‌های کانتینر/مرورگر sandbox اکنون از جدول مشترک SQLite به نام sandbox_registry_entries با ستون‌های نوع‌دار نشست، تصویر، مُهر زمانی، backend/config و پورت مرورگر استفاده می‌کنند. doctor فایل‌های رجیستری JSON قدیمیِ یکپارچه و قطعه‌بندی‌شده را وارد و منابع موفق را حذف می‌کند. خواندن‌های زمان اجرا ستون‌های نوع‌دار ردیف را منبع حقیقت قرار می‌دهند؛ entry_json فقط یک کپی بازپخش/اشکال‌زدایی است.
  • تعهدها اکنون به‌جای یک blob ‏JSON برای کل مخزن، از جدول مشترک نوع‌دار commitments استفاده می‌کنند. زمان اجرا از پرس‌وجوهای نمایه‌شده برای دامنه، پنجره تحویل، سقف چرخشی، وضعیت و تلاش‌ها، همراه با تراکنش‌های همگام SQLite استفاده می‌کند؛ record_json فقط یک کپی بازپخش/اشکال‌زدایی است. تعمیر صریح doctor، فایل قدیمی کامل commitments.json را اعتبارسنجی می‌کند، ردیف‌های جدیدتر SQLite را نگه می‌دارد، نتیجه را راستی‌آزمایی می‌کند و تنها پس از آن منبع بدون تغییر را حذف می‌کند. زمان اجرا هرگز فایل بازنشسته را نمی‌خواند یا نمی‌نویسد.
  • اشتراک‌های Web Push و هویت VAPID تولیدشده اکنون از ردیف‌های مشترک نوع‌دار web_push_subscriptions و web_push_vapid_keys استفاده می‌کنند. ثبت زمان اجرا، پاک‌سازی انقضا و تولید کلید هنگام نخستین استفاده از تراکنش‌های سطح ردیف SQLite استفاده می‌کنند. تعمیر صریح Doctor هر دو مخزن JSON بازنشسته را اعتبارسنجی و پیش از نوشتن در SQLite آن‌ها را مطالبه می‌کند، به‌صورت اتمی واردشان می‌کند، هویت‌های متعارض VAPID را رد می‌کند، نتیجه را راستی‌آزمایی می‌کند و تنها پس از آن مطالبه‌ها را حذف می‌کند. doctor قفل نگه‌داری پوشه وضعیت را در سراسر فرایند ورود نگه می‌دارد تا یک Gateway قدیمی‌تر نتواند فایل‌های بازنشسته را دوباره ایجاد کند. ثبت، تحویل، حذف و تفکیک کلید تا زمانی که Doctor منابع قدیمی در انتظار یا مطالبه‌های قطع‌شده را رفع کند، به‌شکل بسته شکست می‌خورند.
  • تعریف‌های کار Cron، وضعیت زمان‌بندی و تاریخچه اجرا دیگر نویسنده یا خواننده JSON در زمان اجرا ندارند. زمان اجرا از ردیف‌های cron_jobs با ستون‌های نوع‌دار زمان‌بندی، payload، تحویل، هشدار خرابی، نشست، وضعیت و وضعیت زمان اجرا، به‌علاوه جزئیات متعلق به Cron در task_runs برای عیب‌یابی، تحویل، نشست/اجرا، مدل و مجموع توکن‌ها استفاده می‌کند. job_json فقط یک کپی بازپخش/اشکال‌زدایی است؛ state_json عیب‌یابی‌های تو‌در‌توی زمان اجرا را نگه می‌دارد که هنوز فیلدهای پرس‌وجوی پرتکرار ندارند، درحالی‌که زمان اجرا فیلدهای پرتکرار وضعیت را از ستون‌های نوع‌دار بازسازی می‌کند. doctor فایل‌های قدیمی jobs.json، jobs-state.json و runs/*.jsonl را وارد و منابع واردشده را حذف می‌کند. بازنویسی‌های هدف Plugin به‌جای بارگیری و جایگزینی کل مخزن Cron، ردیف‌های منطبق cron_jobs را به‌روزرسانی می‌کنند.
  • راه‌اندازی Gateway نشانگرهای قدیمی notify: true را در تصویر زمان اجرا نادیده می‌گیرد. doctor فقط هنگام تبدیل آن نشانگرها به تحویل صریح SQLite، داده خام بازنشسته cron.webhook را می‌خواند و سپس کلید پیکربندی را حذف می‌کند.
  • صف‌های تحویل خروجی و نشست اکنون وضعیت صف، نوع ورودی، کلید نشست، کانال، هدف، شناسه حساب، تعداد تلاش مجدد، آخرین تلاش/خطا، وضعیت بازیابی و نشانگرهای ارسال پلتفرم را به‌صورت ستون‌های نوع‌دار در جدول مشترک delivery_queue_entries ذخیره می‌کنند. بازیابی زمان اجرا این فیلدهای پرتکرار را از ستون‌های نوع‌دار می‌خواند و تغییرات تلاش مجدد/بازیابی مستقیماً آن ستون‌ها را بدون بازنویسی JSON بازپخش به‌روزرسانی می‌کنند. payload کامل JSON فقط به‌عنوان blob بازپخش/اشکال‌زدایی برای بدنه پیام‌ها و دیگر داده‌های سرد بازپخش باقی می‌ماند.
  • رکوردهای مدیریت‌شده تصاویر خروجی اکنون از ردیف‌های مشترک نوع‌دار managed_outgoing_image_records استفاده می‌کنند. زمان اجرا فقط ستون‌های نوع‌دار را می‌خواند؛ ستون JSON یک کپی بازپخش/اشکال‌زدایی است. بایت‌های اصلی تصویر به‌صورت مصنوعات پیوست نام‌گذاری‌شده در پوشه رسانه مدیریت‌شده باقی می‌مانند.
  • ترجیحات انتخاب‌گر مدل Discord، هش‌های استقرار فرمان و اتصال‌های رشته اکنون از وضعیت مشترک Plugin در SQLite استفاده می‌کنند. برنامه‌های ورود JSON قدیمی آن‌ها در سطح مهاجرت setup/doctor مربوط به Plugin ‏Discord قرار دارند، نه در کد مهاجرت هسته.
  • آشکارسازهای ورود قدیمی Plugin از ماژول‌های نام‌گذاری‌شده برای doctor، مانند doctor-legacy-state.ts یا doctor-state-imports.ts استفاده می‌کنند؛ ماژول‌های عادی زمان اجرای کانال نباید آشکارسازهای JSON قدیمی را وارد کنند.
  • مکان‌نماهای همگام‌سازی BlueBubbles و نشانگرهای حذف تکرار ورودی اکنون از وضعیت مشترک Plugin در SQLite استفاده می‌کنند. برنامه‌های ورود JSON قدیمی آن‌ها در سطح مهاجرت setup/doctor مربوط به Plugin ‏BlueBubbles قرار دارند، نه در کد مهاجرت هسته.
  • offsetهای به‌روزرسانی Telegram، ردیف‌های حافظه نهان برچسب، ردیف‌های حافظه نهان پیام ارسال‌شده، ردیف‌های حافظه نهان نام موضوع و اتصال‌های رشته اکنون از وضعیت مشترک Plugin در SQLite استفاده می‌کنند. برنامه‌های ورود JSON قدیمی آن‌ها در سطح مهاجرت setup/doctor مربوط به Plugin ‏Telegram قرار دارند، نه در کد مهاجرت هسته.
  • مکان‌نماهای همگام‌سازی iMessage، نگاشت‌های شناسه کوتاه پاسخ و ردیف‌های حذف تکرار پژواک ارسال‌شده اکنون از وضعیت مشترک Plugin در SQLite استفاده می‌کنند. فایل‌های قدیمی imessage/catchup/*.json، imessage/reply-cache.jsonl و imessage/sent-echoes.jsonl فقط ورودی doctor هستند.
  • ردیف‌های حذف تکرار پیام Feishu اکنون به‌جای فایل‌های feishu/dedup/*.json یا مخزن دستی بازنشسته dedup.*، از حذف تکرار قابل‌مطالبه هسته (فضاهای نام feishu.dedup.* در وضعیت مشترک Plugin در SQLite) استفاده می‌کنند؛ ورود داده قدیمی انجام نمی‌شود، زیرا حافظه نهان محافظت در برابر بازپخش پس از ارتقا بازسازی می‌شود.
  • گفت‌وگوها، نظرسنجی‌ها، بافرهای بارگذاری در انتظار و آموخته‌های بازخورد Microsoft Teams اکنون از جدول‌های مشترک وضعیت/blob افزونه در SQLite استفاده می‌کنند. مسیر بارگذاری در انتظار از plugin_blob_entries استفاده می‌کند تا بافرهای رسانه به‌جای JSON با کدگذاری base64، به‌صورت BLOBهای SQLite ذخیره شوند. نام helperهای زمان اجرا اکنون به‌جای نام‌گذاری مخزن فایل *-fs، از نام‌گذاری SQLite/وضعیت استفاده می‌کنند و shim قدیمی storePath از این مخزن‌ها حذف شده است. برنامه ورود JSON قدیمی آن در سطح مهاجرت setup/doctor مربوط به Plugin ‏Microsoft Teams قرار دارد.
  • رسانه خروجی میزبانی‌شده Zalo اکنون به‌جای sidecarهای موقت JSON/bin در openclaw-zalo-outbound-media، از SQLite مشترک plugin_blob_entries استفاده می‌کند.
  • HTML و فراداده نمایشگر تفاوت‌ها اکنون به‌جای فایل‌های موقت meta.json/viewer.html از SQLite مشترک plugin_blob_entries استفاده می‌کنند. HTML نمایشگر به‌صورت blob ‏gzip ذخیره می‌شود و فقط هش توکن URL ماندگار می‌شود. خروجی‌های PNG/PDF رندرشده به‌صورت ایجادهای موقت باقی می‌مانند، زیرا تحویل کانال همچنان به مسیر فایل نیاز دارد؛ فراداده انقضای آن‌ها بدون sidecarهای JSON تحت مالکیت SQLite است.
  • سندهای مدیریت‌شده Canvas اکنون به‌جای پوشه پیش‌فرض state/canvas/documents از SQLite مشترک plugin_blob_entries استفاده می‌کنند. میزبان Canvas آن blobها را مستقیماً ارائه می‌کند؛ فایل‌های محلی فقط برای محتوای صریح اپراتور در host.root یا ایجاد موقت، زمانی که خواننده رسانه پایین‌دستی به مسیر نیاز دارد، ساخته می‌شوند.
  • تصمیم‌های ممیزی File Transfer اکنون به‌جای گزارش نامحدود زمان اجرای audit/file-transfer.jsonl از SQLite مشترک plugin_state_entries استفاده می‌کنند. doctor فایل ممیزی JSONL قدیمی را به وضعیت Plugin وارد و پس از ورود پاک، منبع را حذف می‌کند.
  • اجاره‌های فرایند ACPX و هویت نمونه Gateway اکنون از وضعیت مشترک Plugin در SQLite استفاده می‌کنند. doctor فایل قدیمی gateway-instance-id را به وضعیت Plugin وارد و منبع را حذف می‌کند.
  • اسکریپت‌های wrapper تولیدشده ACPX و خانه ایزوله Codex، ایجادهای موقتی زیر ریشه موقت OpenClaw هستند، نه وضعیت پایدار OpenClaw. رکوردهای پایدار زمان اجرای ACPX همان ردیف‌های اجاره SQLite و نمونه Gateway هستند؛ سطح پیکربندی قدیمی ACPX در stateDir حذف شده است، زیرا دیگر هیچ وضعیت زمان اجرایی در آن نوشته نمی‌شود.
  • پیوست‌های رسانه Gateway اکنون از جدول مشترک SQLite در media_blobs به‌عنوان مخزن مرجع بایت استفاده می‌کنند. مسیرهای محلی بازگردانده‌شده به سطوح سازگاری کانال و sandbox، ایجادهای موقت ردیف پایگاه داده‌اند، نه مخزن پایدار رسانه. فهرست‌های مجاز رسانه زمان اجرا دیگر شامل ریشه‌های قدیمی $OPENCLAW_STATE_DIR/media یا ریشه پیکربندی media نیستند؛ آن پوشه‌ها فقط منابع ورود doctor هستند.
  • تکمیل shell دیگر فایل‌های حافظه نهان $OPENCLAW_STATE_DIR/completions/* را نمی‌نویسد. مسیرهای smoke نصب، doctor، به‌روزرسانی و انتشار به‌جای فایل‌های پایدار حافظه نهان تکمیل، از خروجی تکمیل تولیدشده یا source کردن profile استفاده می‌کنند.
  • مرحله‌بندی بارگذاری Skills در Gateway اکنون از ردیف‌های مشترک skill_uploads و skill_upload_chunks استفاده می‌کند. قطعه‌ها هنگام بارگذاری به‌صورت جداگانه تراکنشی باقی می‌مانند، سپس commit یک BLOB آرشیو راستی‌آزمایی‌شده را مونتاژ و ردیف‌های قطعه را حذف می‌کند. نصب‌کننده فقط هنگام اجرای نصب یک مسیر آرشیو موقتِ ایجادشده دریافت می‌کند. doctor به‌جای وارد کردن بارگذاری‌های گذرا، درخت مرحله‌بندی یک‌ساعته بازنشسته در سیستم فایل را کنار می‌گذارد.
  • پیوست‌های درون‌خطی زیرعامل دیگر زیر .openclaw/attachments/* فضای کاری ایجاد نمی‌شوند. مسیر spawn ورودی‌های seed برای VFS ‏SQLite را آماده می‌کند، اجراهای درون‌خطی آن ورودی‌ها را در فضای نام scratch زمان اجرای هر عامل seed می‌کنند و ابزارهای متکی به دیسک، آن scratch در SQLite را برای مسیرهای پیوست overlay می‌کنند. ستون‌های قدیمی رجیستری پوشه پیوست اجرای زیرعامل و hookهای پاک‌سازی حذف شده‌اند.
  • آب‌رسانی تصویر CLI دیگر فایل‌های پایدار حافظه نهان openclaw-cli-images را نگه نمی‌دارد. backendهای خارجی CLI همچنان مسیر فایل دریافت می‌کنند، اما این مسیرها ایجادهای موقت هر اجرا همراه با پاک‌سازی هستند.
  • عیب‌یابی‌های ردیابی حافظه نهان، عیب‌یابی payload ‏Anthropic، عیب‌یابی جریان خام مدل، رویدادهای خط زمانی عیب‌یابی و بسته‌های پایداری Gateway اکنون به‌جای فایل‌های logs/*.jsonl یا logs/stability/*.json، ردیف‌های SQLite می‌نویسند. پرچم‌ها و متغیرهای محیطی بازنویسی مسیر زمان اجرا حذف شده‌اند؛ فرمان‌های export/اشکال‌زدایی می‌توانند فایل‌ها را صراحتاً از ردیف‌های پایگاه داده ایجاد کنند.
  • همراه macOS دیگر نویسنده چرخشی diagnostics.jsonl ندارد. گزارش‌های برنامه به ثبت یکپارچه می‌روند و عیب‌یابی‌های پایدار Gateway مبتنی بر SQLite باقی می‌مانند.
  • فهرست رکورد port-guardian در macOS اکنون به‌جای فایل JSON در Application Support یا blob تک‌نمونه‌ای مبهم، از ردیف‌های مشترک نوع‌دار SQLite در macos_port_guardian_records استفاده می‌کند. همه profileهای برنامه macOS از یک پایگاه داده بومی سراسری میزبان استفاده می‌کنند، زیرا پورت‌های محلی ماشین را هماهنگ می‌کنند. هر عملیات دفترکل تا زمانی که یک نسخه قدیمی‌تر برنامه با قابلیت نوشتن JSON در حال اجرا باشد، مسدود می‌شود. مهاجرت فقط برای گرفتن snapshot و سپس اعتبارسنجی دوباره منبع، به پروتکل پایدار قفل فایل دفترکل قدیمی می‌پیوندد. بدون نگه‌داشتن آن قفل، هر ردیف قدیمی را از واقعیت‌های زنده فرمان و شروع فرایند تفکیک می‌کند، سپس ردیف‌های معتبر SQLite را دوباره می‌خواند، برنامه را اعمال می‌کند، هر رسید را راستی‌آزمایی می‌کند و منبع را حذف می‌کند. تلاش‌های مجدد حذف برای ردیف‌های ازدست‌رفته دوباره برنامه‌ریزی می‌کنند تا رسیدهای بازنشسته و کهنه نتوانند احیا شوند. قفل کوتاه‌عمر باقی می‌ماند تا پس از spawn شدن SSH، یک نویسنده قدیمی را سرگردان نکند. گذار عمداً یک‌طرفه است: زمان اجرای حالت پایدار هرگز JSON را نمی‌خواند، تصویر نمی‌کند یا نمی‌نویسد و بازگشت به buildهای فقط JSON رسیدهای جدیدتر SQLite را حفظ نمی‌کند.
  • قفل‌های تک‌نمونه Gateway اکنون به‌جای فایل‌های قفل پوشه موقت، از ردیف‌های مشترک نوع‌دار SQLite در state_leases و تحت دامنه gateway_locks استفاده می‌کنند. مستندات عیب‌یابی Fly و OAuth اکنون به‌جای پاک‌سازی قدیمی قفل فایل، به قفل اجاره/تازه‌سازی احراز هویت SQLite اشاره می‌کنند.
  • وضعیت نشانگر راه‌اندازی مجدد Gateway اکنون به‌جای restart-sentinel.json از ردیف‌های SQLite اشتراکی نوع‌دار gateway_restart_sentinel استفاده می‌کند؛ زمان اجرا نوع، وضعیت، مسیریابی، پیام، ادامه و آمار نشانگر را از ستون‌های نوع‌دار می‌خواند. این ستون‌ها مرجع معتبر هستند؛ payload_json فقط یک سایه برای بازپخش/اشکال‌زدایی است. مسیرهای خواندن، نوشتن و پاک‌سازی زمان اجرا فقط از SQLite استفاده می‌کنند. یک ماژول محدود مهاجرت وضعیت هنگام راه‌اندازی و در Doctor اجرا می‌شود تا یک نشانگر قدیمی‌تر و اعتبارسنجی‌شده پس از به‌روزرسانی را پیش از بازیابی عادی راه‌اندازی مجدد وارد کند، ردیف نوع‌دار را تأیید کند و فایل مبدأ را حذف کند. هیچ ماژول زمان اجرای پایدار فایل قدیمی را نمی‌خواند، نمی‌نویسد یا پاک‌سازی نمی‌کند.
  • قصد راه‌اندازی مجدد Gateway و وضعیت تحویل به سرپرست اکنون به‌جای فایل‌های جانبی gateway-restart-intent.json و gateway-supervisor-restart-handoff.json از ردیف‌های نوع‌دار SQLite اشتراکی gateway_restart_intent و gateway_restart_handoff استفاده می‌کنند.
  • هماهنگی تک‌نمونه Gateway اکنون به‌جای نوشتن فایل‌های gateway.<hash>.lock، از ردیف‌های نوع‌دار state_leases در gateway_locks استفاده می‌کند. ردیف اجاره مالک قفل، انقضا، Heartbeat و محتوای اشکال‌زدایی را در اختیار دارد؛ SQLite مالک مرز اتمی اخذ/آزادسازی است. گزینه بازنشسته‌شده دایرکتوری قفل فایل حذف شده است؛ آزمون‌ها مستقیماً از هویت ردیف SQLite استفاده می‌کنند.
  • یار قدیمی و بدون ارجاع گزارش مصرف Cron که فایل‌های cron/runs/*.jsonl را پویش می‌کرد حذف شد. گزارش‌های تاریخچه اجرای Cron ردیف‌های متعلق به Cron در task_runs را می‌خوانند.
  • بازیابی راه‌اندازی مجدد نشست اصلی اکنون به‌جای پویش دایرکتوری‌های agents/*/sessions، عامل‌های نامزد را از طریق رجیستری SQLite در agent_databases شناسایی می‌کند.
  • بازیابی خرابی نشست Gemini اکنون فقط ردیف نشست SQLite را حذف می‌کند؛ دیگر به دروازه قدیمی storePath نیاز ندارد و برای حذف پیوند مسیر مشتق‌شده رونوشت JSONL تلاش نمی‌کند.
  • مدیریت بازنویسی مسیر اکنون مقادیر لفظی محیطی undefined/null را تنظیم‌نشده در نظر می‌گیرد و از ایجاد تصادفی پایگاه‌های داده undefined/state/*.sqlite در ریشه مخزن هنگام آزمون‌ها یا تحویل‌های پوسته جلوگیری می‌کند.
  • اثر انگشت‌های سلامت پیکربندی اکنون به‌جای logs/config-health.json از ردیف‌های نوع‌دار SQLite اشتراکی config_health_entries استفاده می‌کنند و فایل پیکربندی عادی را به‌عنوان تنها سند پیکربندی غیراعتباری نگه می‌دارند. همراه macOS فقط وضعیت سلامت محلیِ فرایند را نگه می‌دارد و فایل جانبی JSON قدیمی را دوباره ایجاد نمی‌کند.
  • زمان اجرای پروفایل احراز هویت دیگر فایل‌های JSON اعتبارنامه را وارد نمی‌کند یا نمی‌نویسد. مخزن معتبر اعتبارنامه SQLite است؛ auth-profiles.json، فایل‌های مختص هر عامل auth.json و فایل اشتراکی credentials/oauth.json ورودی‌های مهاجرت Doctor هستند که پس از واردسازی حذف می‌شوند.
  • آزمون‌های ذخیره/وضعیت پروفایل احراز هویت اکنون جداول نوع‌دار احراز هویت SQLite را مستقیماً بررسی می‌کنند و نام فایل‌های قدیمی پروفایل احراز هویت را فقط برای ورودی‌های مهاجرت Doctor به‌کار می‌برند.
  • openclaw secrets apply فقط فایل پیکربندی، فایل محیط و مخزن SQLite پروفایل احراز هویت را پاک‌سازی می‌کند. دیگر منطق سازگاری برای ویرایش auth.json بازنشسته‌شده مختص هر عامل را ندارد؛ Doctor مسئول واردسازی و حذف آن فایل است.
  • برنامه‌های مهاجرت راز Hermes، پروفایل‌های واردشده کلید API را مستقیماً در مخزن SQLite پروفایل احراز هویت اعمال می‌کنند. دیگر auth-profiles.json را به‌عنوان مقصد میانی نمی‌نویسد یا تأیید نمی‌کند.
  • مستندات احراز هویت کاربرمحور اکنون state/openclaw.sqlite#table/auth_profile_stores/<agentDir> را شرح می‌دهند، به‌جای آنکه به کاربران بگویند auth-profiles.json را بررسی یا کپی کنند؛ نام‌های قدیمی JSON مربوط به OAuth/احراز هویت فقط به‌عنوان ورودی‌های واردسازی Doctor مستند باقی می‌مانند.
  • نشست‌های OAuth مربوط به MCP اکنون از ردیف‌های نسخه‌دار mcp_oauth_stores در state/openclaw.sqlite اشتراکی استفاده می‌کنند. اشیای توکن، ثبت کلاینت و کشف متعلق به SDK همچنان یک محتوای JSON اعتبارسنجی‌شده باقی می‌مانند تا فیلدهای توسعه وابستگی حفظ شوند، درحالی‌که هر خواندن/تغییر/نوشتن در یک تراکنش کوتاه Kysely ثبت می‌شود. یک اجاره SQLite اشتراکی، تازه‌سازی، ورود و خروج را سریالی می‌کند؛ انتقال‌های تعبیه‌شده MCP دیگر اجازه نمی‌دهند SDK مربوط به MCP خارج از آن اجاره تازه‌سازی کند. Doctor منحصراً مخزن‌های بازنشسته‌شده mcp-oauth/*.json را همراه رسیدهای مبدأ وارد و حذف می‌کند و زمان اجرا هیچ بازگشتی به فایل ندارد.
  • یارهای مسیر وضعیت هسته دیگر فایل بازنشسته‌شده credentials/oauth.json را در معرض قرار نمی‌دهند. نام فایل قدیمی فقط در مسیر واردسازی احراز هویت Doctor محلی است.
  • مستندات نصب، امنیت، راه‌اندازی اولیه، احراز هویت مدل و SecretRef اکنون به‌جای فایل‌های JSON پروفایل احراز هویت مختص هر عامل، ردیف‌های SQLite پروفایل احراز هویت و پشتیبان‌گیری/مهاجرت کل وضعیت را شرح می‌دهند.
  • کشف مدل PI اکنون اعتبارنامه‌های معتبر را به فضای ذخیره‌سازی احراز هویت درون‌حافظه‌ای pi-coding-agent می‌فرستد. دیگر هنگام کشف، auth.json مختص هر عامل را ایجاد، پاک‌سازی یا نمی‌نویسد.
  • تنظیمات فعال‌سازی و مسیریابی Voice Wake اکنون به‌جای settings/voicewake.json، settings/voicewake-routing.json یا ردیف‌های عمومی مبهم، از جداول نوع‌دار SQLite اشتراکی استفاده می‌کنند؛ Doctor فایل‌های JSON قدیمی را وارد می‌کند و پس از مهاجرت موفق آن‌ها را حذف می‌کند.
  • وضعیت بررسی به‌روزرسانی اکنون به‌جای update-check.json یا یک حباب عمومی مبهم، از ردیف نوع‌دار اشتراکی update_check_state استفاده می‌کند؛ Doctor فایل JSON قدیمی را وارد می‌کند و پس از مهاجرت موفق آن را حذف می‌کند.
  • وضعیت سلامت پیکربندی اکنون به‌جای logs/config-health.json یا یک حباب عمومی مبهم، از ردیف‌های نوع‌دار اشتراکی config_health_entries استفاده می‌کند؛ Doctor فایل JSON قدیمی را وارد می‌کند و پس از مهاجرت موفق آن را حذف می‌کند.
  • تأییدهای اتصال مکالمه Plugin اکنون به‌جای وضعیت مبهم SQLite اشتراکی یا plugin-binding-approvals.json از ردیف‌های نوع‌دار plugin_binding_approvals استفاده می‌کنند؛ فایل قدیمی ورودی مهاجرت Doctor است.
  • اتصال‌های عمومی مکالمه جاری اکنون به‌جای بازنویسی bindings/current-conversations.json، ردیف‌های نوع‌دار current_conversation_bindings را ذخیره می‌کنند؛ Doctor فایل JSON قدیمی را وارد می‌کند و پس از مهاجرت موفق آن را حذف می‌کند.
  • دفترهای همگام‌سازی منبع واردشده Memory Wiki اکنون به‌ازای هر کلید خزانه/منبع یک ردیف وضعیت Plugin در SQLite ذخیره می‌کنند، به‌جای بازنویسی .openclaw-wiki/source-sync.json؛ ارائه‌دهنده مهاجرت، دفتر JSON قدیمی را وارد و حذف می‌کند.
  • رکوردهای اجرای واردسازی ChatGPT در Memory Wiki اکنون به‌ازای هر شناسه خزانه/اجرا یک ردیف وضعیت Plugin در SQLite ذخیره می‌کنند، به‌جای نوشتن .openclaw-wiki/import-runs/*.json. عکس‌های فوری بازگردانی تا زمانی که بایگانی عکس فوری اجرای واردسازی به فضای ذخیره‌سازی حباب منتقل شود، همچنان فایل‌های صریح خزانه باقی می‌مانند.
  • چکیده‌های کامپایل‌شده Memory Wiki اکنون به‌جای نوشتن .openclaw-wiki/cache/agent-digest.json و .openclaw-wiki/cache/claims.jsonl، ردیف‌های فشرده حباب Plugin در SQLite ذخیره می‌کنند. حافظه نهان بازسازی‌پذیر است، بنابراین Doctor فایل‌های قدیمی حافظه نهان را بدون واردسازی حذف می‌کند.
  • ردیابی نصب Skills از ClawHub اکنون به‌ازای هر فضای کاری/Skill یک ردیف وضعیت Plugin در SQLite ذخیره می‌کند، به‌جای آنکه در زمان اجرا فایل‌های جانبی .clawhub/lock.json و .clawhub/origin.json را بنویسد یا بخواند. کد زمان اجرا به‌جای انتزاع‌های لاک‌فایل/مبدأ با شکل فایل، از اشیای وضعیت نصب ردیابی‌شده استفاده می‌کند. Doctor فایل‌های جانبی قدیمی را از فضاهای کاری عامل پیکربندی‌شده وارد می‌کند و پس از واردسازی پاک آن‌ها را حذف می‌کند.
  • فهرست Pluginهای نصب‌شده اکنون به‌جای plugins/installs.json، ردیف تک‌نمونه نوع‌دار SQLite اشتراکی installed_plugin_index را می‌خواند و می‌نویسد؛ فایل JSON قدیمی فقط ورودی مهاجرت Doctor است و پس از واردسازی حذف می‌شود.
  • یار مسیر قدیمی plugins/installs.json اکنون در کد قدیمی Doctor قرار دارد. ماژول‌های فهرست Plugin زمان اجرا فقط گزینه‌های ماندگاری مبتنی بر SQLite را ارائه می‌کنند، نه مسیر فایل JSON.
  • نشانگر راه‌اندازی مجدد Gateway، قصد راه‌اندازی مجدد و وضعیت تحویل به سرپرست اکنون به‌جای حباب‌های عمومی مبهم، از ردیف‌های نوع‌دار SQLite اشتراکی (gateway_restart_sentinel، gateway_restart_intent و gateway_restart_handoff) استفاده می‌کنند. کد راه‌اندازی مجدد زمان اجرا هیچ قرارداد نشانگر/قصد/تحویل با شکل فایل ندارد.
  • حافظه نهان همگام‌سازی Matrix، فراداده ذخیره‌سازی، اتصال‌های رشته، نشانگرهای حذف تکرار ورودی، وضعیت زمان انتظار تأیید راه‌اندازی، عکس‌های فوری رمزنگاری IndexedDB مربوط به SDK، اعتبارنامه‌ها و کلیدهای بازیابی اکنون از جداول وضعیت/حباب Plugin در SQLite اشتراکی استفاده می‌کنند. ساختارهای مسیر زمان اجرا دیگر مسیر فراداده storage-meta.json را در معرض قرار نمی‌دهند؛ آن نام فایل فقط ورودی مهاجرت قدیمی است. برنامه واردسازی JSON قدیمی آن‌ها در سطح مهاجرت راه‌اندازی/Doctor در Plugin مربوط به Matrix قرار دارد. نشانگرهای حذف تکرار ورودی از حذف تکرار قابل‌ادعای هسته استفاده می‌کنند (فضاهای نام matrix.inbound-dedupe.* در پایگاه داده وضعیت اشتراکی)؛ مهاجرت وضعیت Doctor در Matrix، ردیف‌های بازنشسته‌شده inbound-dedupe مختص هر ریشه و inbound-dedupe.json را یک‌بار وارد می‌کند، سپس زمان اجرا فقط مخزن حذف تکرار قابل‌ادعا را می‌خواند.
  • راه‌اندازی Matrix دیگر وضعیت قدیمی فایل Matrix را پویش، گزارش یا تکمیل نمی‌کند. شناسایی فایل Matrix، ایجاد عکس فوری رمزنگاری قدیمی، وضعیت مهاجرت بازیابی کلید اتاق، واردسازی و حذف مبدأ همگی متعلق به Doctor هستند.
  • بارل‌های مهاجرت زمان اجرای Matrix حذف شدند. یارهای شناسایی و تغییر وضعیت/رمزنگاری قدیمی مستقیماً توسط Doctor مربوط به Matrix وارد می‌شوند، به‌جای آنکه بخشی از سطح API زمان اجرا باشند.
  • نشانگرهای استفاده مجدد از عکس فوری مهاجرت Matrix اکنون به‌جای matrix/migration-snapshot.json در وضعیت Plugin در SQLite قرار دارند؛ Doctor همچنان می‌تواند همان بایگانی تأییدشده پیش از مهاجرت را بدون نوشتن فایل وضعیت جانبی دوباره استفاده کند.
  • مکان‌نماهای گذرگاه Nostr و وضعیت انتشار پروفایل اکنون از وضعیت Plugin در SQLite اشتراکی استفاده می‌کنند. برنامه واردسازی JSON قدیمی آن‌ها در سطح مهاجرت راه‌اندازی/Doctor در Plugin مربوط به Nostr قرار دارد.
  • کلیدهای تغییر وضعیت نشست Active Memory اکنون به‌جای session-toggles.json از وضعیت Plugin در SQLite اشتراکی استفاده می‌کنند؛ روشن‌کردن دوباره حافظه، به‌جای بازنویسی یک شیء JSON، ردیف را حذف می‌کند.
  • پیشنهادها و شمارنده‌های بازبینی Skill Workshop اکنون به‌جای مخزن‌های مختص هر فضای کاری skill-workshop/<workspace>.json، از وضعیت Plugin در SQLite اشتراکی استفاده می‌کنند. هر پیشنهاد یک ردیف جداگانه در skill-workshop/proposals است و شمارنده بازبینی یک ردیف جداگانه در skill-workshop/reviews است.
  • اجراهای زیرعامل بازبین Skill Workshop اکنون به‌جای ایجاد مسیرهای نشست جانبی skill-workshop/<sessionId>.json، از حل‌کننده رونوشت نشست زمان اجرا استفاده می‌کنند.
  • اجاره‌های فرایند ACPX اکنون به‌جای رجیستری تمام‌فایلی process-leases.json، از وضعیت Plugin در SQLite اشتراکی تحت acpx/process-leases استفاده می‌کنند. هر اجاره در ردیف خودش ذخیره می‌شود و جمع‌آوری فرایندهای کهنه هنگام راه‌اندازی را بدون مسیر بازنویسی JSON در زمان اجرا حفظ می‌کند.
  • اسکریپت‌های پوشاننده ACPX و خانه ایزوله Codex در ریشه موقت OpenClaw تولید می‌شوند. در صورت نیاز دوباره ایجاد می‌شوند و ورودی پشتیبان‌گیری یا مهاجرت نیستند.
  • ماندگاری رجیستری اجرای زیرعامل از ردیف‌های نوع‌دار اشتراکی subagent_runs استفاده می‌کند. مسیر قدیمی subagents/runs.json اکنون فقط ورودی پاک‌سازی Doctor است. Doctor آن را تحت قفل نگه‌داری وضعیت تصاحب می‌کند، تصمیم دورریزی را در SQLite ثبت می‌کند و بدون واردسازی وضعیت گذرای اجرا آن را حذف می‌کند. هیچ خواننده، نویسنده، حافظه نهان یا بازگشت JSON در زمان اجرا باقی نمانده است؛ بازیابی میان‌نسخه‌ای اجراهای درحال‌پرواز که فقط در فایل هستند، عمداً در این مرز بازنشستگی پشتیبانی نمی‌شود. آزمون‌های زمان اجرا دیگر برای اثبات رفتار رجیستری، فیکسچرهای نامعتبر یا خالی runs.json ایجاد نمی‌کنند؛ آن‌ها ردیف‌های SQLite را مستقیماً مقداردهی/خواندن می‌کنند.
  • پشتیبان‌گیری پیش از بایگانی، دایرکتوری وضعیت را مرحله‌بندی می‌کند، فایل‌های غیرپایگاه‌داده را کپی می‌کند، از پایگاه‌های داده با پشتیبان‌گیری آنلاین به‌همراه VACUUM آفلاین عکس فوری می‌گیرد، فایل‌های جانبی زنده WAL/SHM را حذف می‌کند، فراداده عکس فوری را در مانیفست بایگانی ثبت می‌کند و اجراهای تکمیل‌شده پشتیبان‌گیری را همراه مانیفست بایگانی در SQLite ثبت می‌کند. openclaw backup create بایگانی نوشته‌شده را به‌طور پیش‌فرض اعتبارسنجی می‌کند؛ --no-verify مسیر سریع صریح است.
  • openclaw backup restore پیش از استخراج، بایگانی را اعتبارسنجی می‌کند، از مانیفست نرمال‌شده تأییدکننده دوباره استفاده می‌کند و دارایی‌های تأییدشده مانیفست را در مسیرهای مبدأ ثبت‌شده‌شان بازیابی می‌کند. برای نوشتن به --yes نیاز دارد و از --dry-run برای برنامه بازیابی پشتیبانی می‌کند.
  • فیلتر قدیمی مسیرهای فرّار پشتیبان‌گیری حذف شده است. پشتیبان‌گیری دیگر برای فایل‌های قدیمی JSON/JSONL نشست یا Cron به فهرست پرش tar زنده نیاز ندارد، زیرا عکس‌های فوری SQLite پیش از ایجاد بایگانی مرحله‌بندی می‌شوند.
  • آماده‌سازی سادهٔ فضای کاری برای راه‌اندازی و آغازبه‌کار دیگر دایرکتوری‌های agents/<agentId>/sessions/ را ایجاد نمی‌کند. فقط پیکربندی/فضای کاری را ایجاد می‌کند؛ ردیف‌های نشست SQLite و ردیف‌های رونوشت در صورت نیاز در پایگاه دادهٔ مختص هر عامل ایجاد می‌شوند.
  • ترمیم مجوزهای امنیتی اکنون به‌جای sessions.json و فایل‌های رونوشت JSONL، پایگاه‌های دادهٔ SQLite سراسری و مختص هر عامل به‌همراه فایل‌های جانبی WAL/SHM را هدف قرار می‌دهد.
  • نام‌های زمان اجرای رجیستری سندباکس اکنون به‌جای انتقال اصطلاحات قدیمی رجیستری JSON به مخزن فعال، انواع رجیستری SQLite را مستقیماً توصیف می‌کنند.
  • openclaw reset --scope config+creds+sessions پایگاه‌های دادهٔ مختص هر عامل openclaw-agent.sqlite را به‌همراه فایل‌های جانبی WAL/SHM حذف می‌کند، نه فقط دایرکتوری‌های قدیمی sessions/ را.
  • توابع کمکی نشست تجمیعی Gateway اکنون از نام‌های ورودی‌محور استفاده می‌کنند: loadCombinedSessionEntriesForGateway مقدار { databasePath, entries } را برمی‌گرداند. نام‌گذاری قدیمی مخزن ترکیبی از فراخوان‌های زمان اجرا حذف شده است.
  • مقداردهی اولیهٔ کانال MCP در Docker اکنون به‌جای ایجاد sessions.json و یک رونوشت JSONL، ردیف نشست اصلی و رویدادهای رونوشت را در پایگاه دادهٔ SQLite مختص هر عامل می‌نویسد.
  • قلاب داخلی حافظهٔ نشست اکنون زمینهٔ نشست قبلی را با {agentId, sessionId} از SQLite بازیابی می‌کند. این قلاب دیگر مسیرهای رونوشت یا دایرکتوری‌های workspace/sessions را پیمایش، ذخیره یا تولید نمی‌کند.
  • قلاب داخلی ثبت‌کنندهٔ فرمان اکنون به‌جای افزودن به logs/commands.log، ردیف‌های ممیزی فرمان را در جدول مشترک command_log_entries در SQLite می‌نویسد.
  • فهرست‌های مجاز جفت‌سازی کانال اکنون در زمان اجرا فقط توابع کمکی خواندن/نوشتن مبتنی بر SQLite را ارائه می‌کنند. تحلیل‌گر منسوخ مسیر در SDK افزونه برای سازگاری مهاجرت باقی می‌ماند؛ خوانندگان فایل فقط در کد مهاجرت وضعیت doctor قرار دارند.
  • migration_runs اجرای مهاجرت‌های وضعیت قدیمی را با وضعیت، مُهرهای زمانی و گزارش‌های JSON ثبت می‌کند.
  • migration_sources هر منبع فایل قدیمی واردشده را با هش، اندازه، تعداد رکوردها، جدول مقصد، شناسهٔ اجرا، وضعیت و وضعیت حذف منبع ثبت می‌کند.
  • backup_runs مسیرهای بایگانی پشتیبان، وضعیت و مانیفست‌های JSON را ثبت می‌کند.
  • طرحوارهٔ سراسری جدول رجیستری بلااستفادهٔ agents را نگه نمی‌دارد. کشف پایگاه دادهٔ عامل تا زمانی که زمان اجرا مالک واقعی رکورد عامل داشته باشد، رجیستری معیار agent_databases است.
  • پیکربندی کاتالوگ مدل تولیدشده در ردیف‌های نوع‌دار سراسری SQLite با نام agent_model_catalogs و کلید دایرکتوری عامل ذخیره می‌شود. فراخوان‌های زمان اجرا از ensureOpenClawModelCatalog استفاده می‌کنند؛ هیچ API سازگاری models.json در کد زمان اجرا وجود ندارد. پیاده‌سازی در SQLite می‌نویسد و رجیستری تعبیه‌شدهٔ PI از بار دادهٔ ذخیره‌شده پر می‌شود، بدون آنکه فایل models.json ایجاد شود.
  • خروجی اختیاری memory.qmd.sessions ردیف‌های معیار رونوشت را از پایگاه دادهٔ مختص هر عامل می‌خواند و Markdown پاک‌سازی‌شده را زیر خانهٔ QMD به‌عنوان یک مصنوع ورودی صریح QMD تولید می‌کند. بنابراین مجموعه‌های نشست QMD و نگاشت‌های هویت مصنوع همچنان بخشی از پل پیکربندی‌شدهٔ ابزار خارجی باقی می‌مانند؛ آن‌ها دومین مخزن معیار رونوشت نیستند.
  • فایل index.sqlite متعلق به خود QMD، پیکربندی YAML مجموعه و بارگیری‌های مدل، مصنوعات ابزار خارجی زیر ~/.openclaw/agents/<agentId>/qmd باقی می‌مانند؛ آن‌ها در plugin_blob_entries آینه نمی‌شوند. هماهنگی QMD تحت مالکیت OpenClaw پایگاه‌داده‌محور است: state_leases مشترک، جاسازی‌ها را به‌صورت سراسری سریالی می‌کند و state_leases مختص هر عامل، نویسندگان مجموعه/به‌روزرسانی/جاسازی را سریالی می‌کند. زمان اجرا هیچ فایل جانبی قفل QMD ایجاد نمی‌کند.
  • Plugin اختیاری memory-lancedb دیگر ~/.openclaw/memory/lancedb را به‌عنوان مخزنی ضمنی تحت مدیریت OpenClaw ایجاد نمی‌کند. این یک بک‌اند خارجی LanceDB است و تا زمانی که متصدی یک dbPath صریح را پیکربندی نکند، غیرفعال می‌ماند.
  • check:database-first-legacy-stores کد منبع جدید زمان اجرا را که نام‌های مخزن قدیمی را با APIهای نوشتن‌محور سامانهٔ فایل جفت می‌کند، ناموفق می‌سازد. همچنین کد منبع زمان اجرا را که نشانگرهای بازنشستهٔ پل رونوشت transcriptLocator یا sqlite-transcript://... را دوباره معرفی کند، ناموفق می‌سازد. کد مهاجرت، doctor، واردسازی و خروجی صریح غیرنشستی همچنان مجاز است. نام‌های گسترده‌تر قرارداد قدیمی مانند sessionFile،‏ storePath و نماهای قدیمی عصر فایل SessionManager هنوز مالکان فعلی دارند و پیش از آنکه بتوانند به بررسی اجباری پیش از اجرا تبدیل شوند، به کار جداگانه‌ای برای محافظ مهاجرت نیاز دارند. این محافظ اکنون مخازن زمان اجرای cache/*.json، فایل‌های جانبی عمومی thread-bindings.json، وضعیت Cron/گزارش اجرای JSON،‏ JSON سلامت پیکربندی، فایل‌های جانبی راه‌اندازی مجدد و قفل، تنظیمات Voice Wake، تأییدیه‌های اتصال Plugin، JSON نمایهٔ Pluginهای نصب‌شده، ممیزی JSONL انتقال فایل، گزارش‌های فعالیت Memory Wiki، گزارش متنی داخلی قدیمی command-logger و گزینه‌های عیب‌یابی JSONL جریان خام pi-mono را نیز پوشش می‌دهد. همچنین نام‌های قدیمی ماژول‌های وضعیت قدیمی doctor در سطح ریشه را ممنوع می‌کند تا کد سازگاری زیر src/commands/doctor/ باقی بماند. کنترل‌کننده‌های اشکال‌زدایی Android نیز به‌جای آماده‌سازی فایل‌های کش camera_debug.log یا debug_logs.txt، از خروجی logcat/درون‌حافظه‌ای استفاده می‌کنند.

شکل شِمای هدف

شِماها را صریح نگه دارید. وضعیت زمان‌اجرای تحت مالکیت میزبان از جدول‌های نوع‌دار استفاده می‌کند. وضعیت مات و تحت مالکیت 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)skill_upload_chunks(upload_id, byte_offset, size_bytes, chunk_blob)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, relay_origin, topic, environment, distribution, token_debug_suffix, updated_at_ms)apns_registration_tombstones(node_id, deleted_at_ms)node_host_config(config_key, version, node_id, token, display_name, gateway_host, gateway_port, gateway_tls, gateway_tls_fingerprint, gateway_context_path, 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)workspace_path_aliases(alias_key, alias_path, workspace_key, workspace_path, updated_at_ms)workspace_attestations(workspace_key, attested_at_ms, updated_at_ms)workspace_generated_bootstrap_hashes(workspace_key, filename, sha256)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, agent_id, 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, cleanup_pending)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_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(id, 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)

memory_index_sources.id کلید اصلی عدد صحیح پایدار است؛ (path, source) همچنان یکتا می‌ماند.

جست‌وجوی آینده می‌تواند جدول‌های 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، اندازه، هش و جدول هدف کلیدگذاری می‌شوند.
  • فایل‌های منبع موفق پس از commit شدن پایگاه داده هدف، حذف یا بایگانی می‌شوند.
  • واردکردن‌های ناموفق منبع را دست‌نخورده باقی می‌گذارند و هشداری را در migration_runs ثبت می‌کنند.
  • پس از وجود مهاجرت، کد زمان‌اجرا فقط SQLite را می‌خواند.
  • هیچ مسیر تنزل نسخه/صدور به فایل‌های زمان‌اجرا لازم نیست.

موجودی مهاجرت

این موارد را به پایگاه داده سراسری منتقل کنید:

  • نوشتن‌های زمان اجرای رجیستری وظایف اکنون از پایگاه دادهٔ مشترک استفاده می‌کنند؛ واردکنندهٔ سایدکارِ منتشرنشدهٔ tasks/runs.sqlite حذف شده است. ذخیرهٔ اسنپ‌شات‌ها بر اساس شناسهٔ وظیفه upsert می‌کند و فقط ردیف‌های وظیفه/تحویلِ مفقود را حذف می‌کند.
  • نوشتن‌های زمان اجرای Task Flow اکنون از پایگاه دادهٔ مشترک استفاده می‌کنند؛ واردکنندهٔ سایدکارِ منتشرنشدهٔ tasks/flows/registry.sqlite حذف شده است. ذخیرهٔ اسنپ‌شات‌ها بر اساس شناسهٔ جریان upsert می‌کند و فقط ردیف‌های جریانِ مفقود را حذف می‌کند.
  • نوشتن‌های زمان اجرای وضعیت Plugin اکنون از پایگاه دادهٔ مشترک استفاده می‌کنند؛ واردکنندهٔ سایدکارِ منتشرنشدهٔ plugin-state/state.sqlite حذف شده است.
  • جست‌وجوی حافظهٔ داخلی دیگر به‌طور پیش‌فرض از memory/<agentId>.sqlite استفاده نمی‌کند؛ جدول‌های ایندکس آن در پایگاه دادهٔ عاملِ مالک قرار دارند و انتخاب صریح سایدکارِ memorySearch.store.path به مهاجرت پیکربندی doctor منتقل و بازنشسته شده است.
  • ایندکس‌گذاری مجدد حافظهٔ داخلی فقط جدول‌های متعلق به حافظه را در پایگاه دادهٔ عامل بازنشانی می‌کند. این فرایند نباید کل فایل SQLite را جایگزین کند، زیرا همان پایگاه داده مالک نشست‌ها، رونوشت‌ها، ردیف‌های VFS، مصنوعات و کش‌های زمان اجرا است.
  • رجیستری‌های کانتینر/مرورگر سندباکس از JSON یکپارچه و شاردشده. نوشتن‌های زمان اجرا اکنون از پایگاه دادهٔ مشترک استفاده می‌کنند؛ واردکردن JSON قدیمی باقی می‌ماند.
  • تعریف‌های کار Cron، وضعیت زمان‌بندی و تاریخچهٔ اجرا اکنون از SQLite مشترک استفاده می‌کنند؛ doctor فایل‌های قدیمی jobs.json، jobs-state.json و cron/runs/*.jsonl را وارد/حذف می‌کند
  • هویت/احراز هویت دستگاه، پوش، بررسی به‌روزرسانی، تعهدات، کش مدل OpenRouter، ایندکس Pluginهای نصب‌شده و اتصال‌های app-server
  • رکوردهای جفت‌سازی دستگاه/Node و راه‌اندازی اولیه اکنون از جدول‌های نوع‌دار SQLite استفاده می‌کنند
  • مشترکان اعلان جفت‌سازی دستگاه و نشانگرهای درخواست تحویل‌شده اکنون به‌جای device-pair-notify.json از جدول مشترک وضعیت Plugin در SQLite استفاده می‌کنند.
  • رکوردهای تماس voice-call اکنون به‌جای calls.jsonl از جدول مشترک وضعیت Plugin در SQLite تحت فضای نام voice-call / calls استفاده می‌کنند؛ CLI این Plugin تاریخچهٔ تماس مبتنی بر SQLite را دنبال و خلاصه می‌کند.
  • نشست‌های Gateway در QQBot، رکوردهای کاربران شناخته‌شده و کش نقل‌قول ref-index اکنون به‌جای session-*.json، known-users.json و ref-index.jsonl از وضعیت Plugin در SQLite تحت فضاهای نام qqbot‏ (gateway-sessions، known-users، ref-index) استفاده می‌کنند. آن فایل‌های قدیمی کش هستند و مهاجرت نمی‌شوند.
  • ترجیحات انتخابگر مدل Discord، هش‌های استقرار فرمان و اتصال‌های رشته اکنون به‌جای model-picker-preferences.json، command-deploy-cache.json و thread-bindings.json از وضعیت Plugin در SQLite تحت فضاهای نام discord ‏(model-picker-preferences، command-deploy-hashes، thread-bindings) استفاده می‌کنند؛ مهاجرت doctor/setup در Discord فایل‌های قدیمی را وارد و حذف می‌کند.
  • مکان‌نماهای catchup و نشانگرهای حذف تکرار ورودی BlueBubbles اکنون به‌جای bluebubbles/catchup/*.json و bluebubbles/inbound-dedupe/*.json از وضعیت Plugin در SQLite تحت فضاهای نام bluebubbles‏ (catchup-cursors، inbound-dedupe) استفاده می‌کنند؛ مهاجرت doctor/setup در BlueBubbles فایل‌های قدیمی را وارد و حذف می‌کند.
  • آفست‌های به‌روزرسانی Telegram، ورودی‌های کش استیکر، ورودی‌های کش پیام زنجیرهٔ پاسخ، ورودی‌های کش پیام ارسال‌شده، ورودی‌های کش نام موضوع و اتصال‌های رشته اکنون به‌جای update-offset-*.json، sticker-cache.json، *.telegram-messages.json، *.telegram-sent-messages.json، *.telegram-topic-names.json و thread-bindings-*.json از وضعیت Plugin در SQLite تحت فضاهای نام telegram ‏(update-offsets، sticker-cache، message-cache، sent-messages، topic-names، thread-bindings) استفاده می‌کنند؛ مهاجرت doctor/setup در Telegram فایل‌های قدیمی را وارد و حذف می‌کند.
  • مکان‌نماهای catchup، نگاشت‌های شناسهٔ کوتاه پاسخ و ردیف‌های حذف تکرار پژواک ارسالی iMessage اکنون به‌جای imessage/catchup/*.json، imessage/reply-cache.jsonl و imessage/sent-echoes.jsonl از وضعیت Plugin در SQLite تحت فضاهای نام imessage‏ (catchup-cursors، reply-cache، sent-echoes) استفاده می‌کنند؛ مهاجرت doctor/setup در iMessage فایل‌های قدیمی را وارد و حذف می‌کند.
  • گفت‌وگوها، نظرسنجی‌ها، توکن‌های SSO و آموخته‌های بازخورد Microsoft Teams اکنون به‌جای msteams-conversations.json، msteams-polls.json، msteams-sso-tokens.json و *.learnings.json از فضاهای نام وضعیت Plugin در SQLite‏ (conversations، polls، sso-tokens، feedback-learnings) استفاده می‌کنند؛ مهاجرت doctor/setup در Microsoft Teams فایل‌های قدیمی را وارد و بایگانی می‌کند. بارگذاری‌های در انتظار یک کش کوتاه‌عمر SQLite هستند و فایل‌های کش JSON قدیمی مهاجرت نمی‌شوند.
  • کش همگام‌سازی Matrix، فرادادهٔ ذخیره‌سازی، اتصال‌های رشته، نشانگرهای حذف تکرار ورودی، وضعیت مهلت انتظار تأیید راه‌اندازی، اعتبارنامه‌ها، کلیدهای بازیابی و اسنپ‌شات‌های رمزنگاری IndexedDB در SDK اکنون به‌جای bot-storage.json، storage-meta.json، thread-bindings.json، inbound-dedupe.json، startup-verification.json، credentials.json، recovery-key.json و crypto-idb-snapshot.json از فضاهای نام وضعیت/blob در Plugin SQLite تحت matrix‏ (sync-store، storage-meta، thread-bindings، matrix.inbound-dedupe.* از طریق حذف تکرار قابل‌تصاحب در هسته، startup-verification، credentials، recovery-key، idb-snapshots) استفاده می‌کنند؛ مهاجرت doctor/setup در Matrix آن فایل‌های قدیمی (و ردیف‌های بازنشستهٔ SQLite در inbound-dedupe به‌ازای هر ریشه) را از ریشه‌های ذخیره‌سازی Matrix در دامنهٔ حساب وارد و حذف می‌کند.
  • مکان‌نماهای گذرگاه Nostr و وضعیت انتشار پروفایل اکنون به‌جای bus-state-*.json و profile-state-*.json از وضعیت Plugin در SQLite تحت فضاهای نام nostr‏ (bus-state، profile-state) استفاده می‌کنند؛ مهاجرت doctor/setup در Nostr فایل‌های قدیمی را وارد و حذف می‌کند.
  • کلیدهای تغییر وضعیت نشست Active Memory اکنون به‌جای session-toggles.json از وضعیت Plugin در SQLite تحت active-memory/session-toggles استفاده می‌کنند.
  • صف‌های پیشنهاد و شمارنده‌های بازبینی Skill Workshop اکنون به‌جای فایل‌های skill-workshop/<workspace>.json به‌ازای هر فضای کاری، از وضعیت Plugin در SQLite تحت skill-workshop/proposals و skill-workshop/reviews استفاده می‌کنند.
  • صف‌های تحویل خروجی و تحویل نشست اکنون به‌جای فایل‌های پایدار delivery-queue/*.json، delivery-queue/failed/*.json و session-delivery-queue/*.json، جدول سراسری SQLite در delivery_queue_entries را تحت نام‌های صف جداگانه ‏(outbound-delivery، session-delivery) به‌اشتراک می‌گذارند. مرحلهٔ وضعیت قدیمی doctor ردیف‌های در انتظار و ناموفق را وارد می‌کند، نشانگرهای تحویل‌شدهٔ منقضی را حذف می‌کند و پس از واردکردن، فایل‌های JSON قدیمی را حذف می‌کند. فیلدهای مسیریابی داغ و تلاش مجدد ستون‌های نوع‌دار هستند؛ محمولهٔ JSON فقط برای بازپخش/اشکال‌زدایی نگه داشته می‌شود.
  • اجاره‌های فرایند ACPX اکنون به‌جای process-leases.json از وضعیت Plugin در SQLite تحت acpx/process-leases استفاده می‌کنند.
  • فرادادهٔ اجرای پشتیبان‌گیری و مهاجرت

این موارد را به پایگاه‌های دادهٔ عامل منتقل کنید:

  • ریشه‌های نشست عامل و محموله‌های ورودی نشست با شکل سازگاری. برای نوشتن‌های زمان اجرا انجام شد: فرادادهٔ داغ نشست در sessions قابل پرس‌وجو است، درحالی‌که محمولهٔ کامل SessionEntry با شکل قدیمی در session_entries باقی می‌ماند.
  • رویدادهای رونوشت عامل. برای نوشتن‌های زمان اجرا انجام شد.
  • نقاط بررسی Compaction و اسنپ‌شات‌های رونوشت. برای نوشتن‌های زمان اجرا انجام شد: کپی‌های رونوشت نقطهٔ بررسی، ردیف‌های رونوشت SQLite هستند و فرادادهٔ نقطهٔ بررسی در transcript_snapshots ثبت می‌شود. کمک‌تابع‌های نقطهٔ بررسی Gateway اکنون این مقادیر را به‌جای فایل‌های منبع، اسنپ‌شات رونوشت می‌نامند.
  • فضاهای نام scratch/فضای کاری VFS عامل. برای نوشتن‌های VFS زمان اجرا انجام شد.
  • محموله‌های پیوست عامل فرعی. برای نوشتن‌های زمان اجرا انجام شد: آن‌ها ورودی‌های seed در VFS مبتنی بر SQLite هستند و هرگز فایل‌های پایدار فضای کاری نیستند.
  • مصنوعات ابزار. برای نوشتن‌های زمان اجرا انجام شد.
  • مصنوعات اجرا. برای نوشتن‌های زمان اجرای worker از طریق جدول run_artifacts به‌ازای هر عامل انجام شد.
  • کش‌های زمان اجرای محلی عامل. برای نوشتن‌های کش با دامنهٔ زمان اجرای worker از طریق جدول cache_entries به‌ازای هر عامل انجام شد. کش‌های مدل در سطح Gateway در پایگاه دادهٔ سراسری باقی می‌مانند، مگر اینکه مختص عامل شوند.
  • لاگ‌های جریان والد ACP. برای نوشتن‌های زمان اجرا انجام شد.
  • نشست‌های دفترکل بازپخش ACP. برای نوشتن‌های زمان اجرا از طریق acp_replay_sessions و acp_replay_events انجام شد؛ acp/event-ledger.json قدیمی فقط به‌عنوان ورودی doctor باقی می‌ماند.
  • فرادادهٔ نشست ACP. برای نوشتن‌های زمان اجرا از طریق acp_sessions انجام شد؛ بلوک‌های قدیمی entry.acp در sessions.json فقط ورودی مهاجرت doctor هستند.
  • سایدکارهای مسیر حرکت، هنگامی که فایل‌های صریح export نیستند. برای نوشتن‌های زمان اجرا انجام شد: ثبت مسیر حرکت، ردیف‌های trajectory_runtime_events را در پایگاه دادهٔ عامل می‌نویسد و مصنوعات دارای دامنهٔ اجرا را در SQLite منعکس می‌کند. سایدکارهای قدیمی فقط ورودی‌های واردکردن doctor هستند؛ export می‌تواند خروجی‌های تازهٔ JSONL برای بستهٔ پشتیبانی ایجاد کند، اما در زمان اجرا سایدکارهای قدیمی مسیر حرکت/رونوشت را نمی‌خواند یا مهاجرت نمی‌دهد. ثبت مسیر حرکت زمان اجرا دامنهٔ SQLite را در دسترس قرار می‌دهد؛ کمک‌تابع‌های مسیر JSONL به پشتیبانی export/اشکال‌زدایی محدود شده‌اند و از ماژول زمان اجرا دوباره صادر نمی‌شوند. فرادادهٔ مسیر حرکت embedded-runner به‌جای ذخیره‌سازی مکان‌یاب رونوشت، هویت {agentId, sessionId, sessionKey} را ثبت می‌کند.

این موارد فعلاً مبتنی بر فایل باقی بمانند:

  • openclaw.json
  • فایل‌های اعتبارنامهٔ ارائه‌دهنده یا CLI
  • مانیفست‌های Plugin/بسته
  • فضاهای کاری کاربر و مخزن‌های Git هنگامی که حالت دیسک انتخاب شده است
  • لاگ‌هایی که برای دنبال‌کردن توسط اپراتور در نظر گرفته شده‌اند، مگر اینکه سطح لاگ مشخصی منتقل شود

برنامهٔ مهاجرت

فاز 0: تثبیت مرز

پیش از انتقال ردیف‌های بیشتر، مرز وضعیت پایدار را صریح کنید:

  • یک جدول migration_runs به پایگاه دادهٔ سراسری اضافه کنید. برای گزارش‌های اجرای مهاجرت وضعیت قدیمی انجام شد.
  • یک سرویس مهاجرت وضعیت واحد و تحت مالکیت doctor برای واردکردن فایل به پایگاه داده اضافه کنید. انجام شد: openclaw doctor --fix از پیاده‌سازی مهاجرت وضعیت قدیمی استفاده می‌کند.
  • plan را فقط‌خواندنی کنید و کاری کنید apply یک نسخهٔ پشتیبان ایجاد کند، وارد کند، تأیید کند و سپس فایل‌های قدیمی را حذف یا قرنطینه کند. انجام شد: doctor یک نسخهٔ پشتیبان تأییدشدهٔ پیش از مهاجرت ایجاد می‌کند، مسیر پشتیبان را به migration_runs می‌دهد و از مسیرهای واردکننده/حذف دوباره استفاده می‌کند.
  • ممنوعیت‌های ایستا اضافه کنید تا کد جدید زمان اجرا نتواند فایل‌های وضعیت قدیمی را بنویسد، درحالی‌که کد مهاجرت و آزمون‌ها همچنان بتوانند آن‌ها را مقداردهی اولیه/بخوانند. برای ذخیره‌گاه‌های قدیمی که درحال‌حاضر مهاجرت شده‌اند انجام شد؛ این محافظ همچنین آزمون‌های تو‌در‌تو را برای قراردادهای ممنوعِ مکان‌یاب رونوشت زمان اجرا اسکن می‌کند.

فاز 1: تکمیل صفحهٔ کنترل سراسری

وضعیت هماهنگی مشترک را در state/openclaw.sqlite نگه دارید:

  • عامل‌ها و رجیستری پایگاه دادهٔ عامل
  • دفترکل‌های وظیفه و Task Flow
  • وضعیت Plugin
  • رجیستری کانتینر/مرورگر سندباکس
  • تاریخچهٔ اجرای Cron/زمان‌بند
  • جفت‌سازی، دستگاه، پوش، بررسی به‌روزرسانی، TUI، کش‌های OpenRouter/مدل و دیگر وضعیت‌های کوچک زمان اجرا با دامنهٔ Gateway
  • فرادادهٔ پشتیبان‌گیری و مهاجرت
  • بایت‌های پیوست رسانه‌ای Gateway. برای نوشتن‌های زمان اجرا انجام شد؛ مسیرهای مستقیم فایل برای سازگاری با ارسال‌کنندگان کانال و staging سندباکس، تحقق‌های موقت هستند. فهرست‌های مجاز زمان اجرا مسیرهای تحقق SQLite را می‌پذیرند، نه ریشه‌های رسانه‌ای قدیمی وضعیت/پیکربندی. doctor فایل‌های رسانه‌ای قدیمی را به media_blobs وارد می‌کند و پس از نوشتن موفق ردیف‌ها، فایل‌های منبع را حذف می‌کند.
  • نشست‌ها، رویدادها و blobهای محمولهٔ ثبت پراکسی اشکال‌زدایی. انجام شد: ثبت‌ها در پایگاه دادهٔ وضعیت مشترک قرار دارند و از طریق راه‌اندازی اولیه، شِما، WAL و تنظیمات مهلت انتظار مشغولی پایگاه دادهٔ وضعیت مشترک باز می‌شوند. بایت‌های محموله با gzip در capture_blobs.data فشرده می‌شوند؛ هیچ جایگزین سایدکار پایگاه دادهٔ زمان اجرای پراکسی اشکال‌زدایی، پوشهٔ blob یا هدف شِما/codegen تولیدشدهٔ مختص ثبت پراکسی وجود ندارد. مهاجرت doctor/راه‌اندازی، ردیف‌های منتشرشدهٔ debug-proxy/capture.sqlite و blobهای محمولهٔ ارجاع‌شده، ازجمله جایگزین‌های فعال محیطی برای پایگاه داده/blob قدیمی را وارد می‌کند، سپس آن منابع را بایگانی می‌کند و گواهی‌های CA را دست‌نخورده باقی می‌گذارد.

این مرحله همچنین بازکننده‌های جانبی تکراری، کمک‌تابع‌های مجوز، راه‌اندازی 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.
  • کمک‌تابع‌های بازنویسی کل ذخیره‌گاه، نویسنده‌های فایل، آزمون‌های صف، هرس نام مستعار و پارامترهای حذف کلید قدیمی از زمان اجرا حذف شده‌اند.
  • برون‌دادهای سازگاری منسوخ‌شده بسته ریشه تا 2026-10-12 به واردکننده ویژه doctor با نام sessions.json واگذار می‌شوند؛ خواندن‌های سازگاری Plugin SDK همچنان ردیف‌های متعارف 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 آفلاین، عکس فوری بگیرید.
  • عکس‌های فوری فشرده پایگاه داده، پیکربندی، اطلاعات اعتبارسنجی خارجی و برون‌بری‌های درخواستی فضای کاری را بایگانی کنید.
  • فایل‌های خام و زنده *.sqlite-wal و *.sqlite-shm را کنار بگذارید.
  • با بازکردن هر عکس فوری پایگاه داده و اجرای PRAGMA integrity_check تأیید کنید. openclaw backup create این تأیید بایگانی را به‌طور پیش‌فرض انجام می‌دهد؛ --no-verify فقط گذر بایگانی پس از نوشتن را رد می‌کند، نه بررسی یکپارچگی ایجاد عکس فوری را.
  • بازیابی، عکس‌های فوری را به مسیرهای مقصدشان کپی می‌کند. پایگاه‌های داده سراسری بازیابی‌شده از نسخه 1 استفاده می‌کنند؛ پایگاه‌های داده به‌ازای هر عامل بازیابی‌شده از نسخه 2 استفاده می‌کنند و عکس‌های فوری نسخه 1 هنگام بازشدن به‌صورت اتمی ارتقا می‌یابند.

مرحله 6: زمان اجرای Worker

تا هنگام استقرار تفکیک پایگاه داده، حالت worker را آزمایشی نگه دارید:

  • Workerها شناسه عامل، شناسه اجرا، حالت سیستم فایل و هویت رجیستری پایگاه داده را دریافت می‌کنند.
  • هر worker اتصال SQLite خودش را باز می‌کند.
  • والد اختیار تحویل کانال، تأییدها، پیکربندی و لغو را حفظ می‌کند.
  • با یک worker به‌ازای هر اجرای فعال شروع کنید؛ تجمیع را فقط پس از پایدارشدن چرخه عمر و مالکیت اتصال پایگاه داده اضافه کنید.

مرحله 7: حذف دنیای قدیمی

برای مدیریت نشست زمان اجرا انجام شد. دنیای قدیمی فقط به‌عنوان ورودی صریح doctor یا خروجی پشتیبانی/برون‌بری مجاز است:

  • هیچ نوشتن زمان اجرایی برای sessions.json، JSONL رونوشت، JSON رجیستری sandbox، SQLite جانبی وظیفه یا SQLite جانبی وضعیت Plugin وجود ندارد.
  • هیچ هرس فایل JSON/نشست، کوتاه‌سازی رونوشت فایل، قفل فایل نشست یا آزمون نشست با شکل قفل وجود ندارد.
  • هیچ برون‌داد سازگاری زمان اجرایی که هدفش به‌روز نگه‌داشتن فایل‌های نشست قدیمی باشد وجود ندارد.
  • برون‌بری‌های صریح پشتیبانی، قالب‌های بایگانی/مادی‌سازی درخواستی کاربر باقی می‌مانند و نباید نام فایل‌ها را دوباره وارد هویت زمان اجرا کنند.

پشتیبان‌گیری و بازیابی

نسخه‌های پشتیبان باید یک فایل بایگانی باشند، اما ثبت پایگاه داده باید بومی SQLite باشد:

  1. تراکنش‌های نوشتن را محدود نگه دارید تا پشتیبان‌گیری برخط بتواند پیشرفت کند.
  2. هر پایگاه داده سراسری و عامل زنده را پیش از ثبت تأیید کنید.
  3. هر پایگاه داده را با پشتیبان‌گیری برخط SQLite در یک پوشه موقت پشتیبان ثبت کنید، سپس اتصال زنده را ببندید و نسخه خصوصی را VACUUM کنید. طرح‌واره‌های Plugin که به قابلیت‌های SQLite تعریف‌شده توسط مالک نیاز دارند، تا زمانی که مالک قرارداد امنی برای عکس فوری ارائه کند، با خطا بسته می‌شوند.
  4. عکس‌های فوری پایگاه داده، فایل پیکربندی، پوشه اطلاعات اعتبارسنجی، فضاهای کاری انتخاب‌شده و یک مانیفست را بایگانی کنید.
  5. شکل فایل هر عکس فوری SQLite را تأیید کنید، سپس پایگاه‌های داده متعارف OpenClaw را باز کنید و PRAGMA integrity_check را همراه با اعتبارسنجی نقش اجرا کنید. طرح‌واره‌های اختصاصی Plugin، مگر آنکه مالکشان تأییدکننده‌ای ارائه کند، مبهم باقی می‌مانند. openclaw backup create این کار را به‌طور پیش‌فرض انجام می‌دهد؛ --no-verify فقط برای ردکردن عمدی گذر بایگانی پس از نوشتن است.

برای قالب اصلی پشتیبان‌گیری به نسخه‌برداری خام فایل‌های زنده *.sqlite، *.sqlite-wal و *.sqlite-shm تکیه نکنید. مانیفست بایگانی باید نقش پایگاه داده، شناسه عامل، نسخه طرح‌واره، مسیر منبع، مسیر عکس فوری، اندازه بایتی و وضعیت یکپارچگی را ثبت کند.

بازیابی باید فایل‌های پایگاه داده سراسری و پایگاه داده عامل را از عکس‌های فوری بایگانی بازسازی کند. طرح‌واره سراسری در نسخه 1 باقی می‌ماند؛ عکس‌های فوری نسخه 1 به‌ازای هر عامل، ارتقای محدود زمان اجرا به نسخه 2 را دریافت می‌کنند. doctor همچنان تنها مالک واردسازی فایل به پایگاه داده است. فرمان بازیابی ابتدا بایگانی را اعتبارسنجی می‌کند، سپس هر دارایی مانیفست را با محموله استخراج‌شده تأییدشده جایگزین می‌کند.

برنامه بازآرایی زمان اجرا

  1. APIهای رجیستری پایگاه داده را اضافه کنید.

    • مسیرهای پایگاه داده سراسری و پایگاه داده به‌ازای هر عامل را تعیین کنید.
    • طرح‌واره سراسری را در user_version = 1 نگه دارید. پایگاه‌های داده به‌ازای هر عامل از نسخه 2 با یک مهاجرت اتمی از شکل منتشرشده منبع حافظه نسخه 1 استفاده می‌کنند.
    • کمک‌تابع‌های بستن/نقطه بازرسی/یکپارچگی را که آزمون‌ها، پشتیبان‌گیری و doctor استفاده می‌کنند، اضافه کنید.
  2. ذخیره‌گاه‌های SQLite جانبی را ادغام کنید.

    • جدول‌های وضعیت Plugin را به پایگاه داده سراسری منتقل کنید. برای نوشتن‌های زمان اجرا انجام شد؛ واردکننده جانبی قدیمی منتشرنشده حذف شده است.
    • جدول‌های رجیستری وظیفه را به پایگاه داده سراسری منتقل کنید. برای نوشتن‌های زمان اجرا انجام شد؛ واردکننده جانبی قدیمی منتشرنشده حذف شده است.
    • جدول‌های جریان وظیفه را به پایگاه داده سراسری منتقل کنید. برای نوشتن‌های زمان اجرا انجام شد؛ واردکننده جانبی قدیمی منتشرنشده حذف شده است.
    • جدول‌های داخلی جست‌وجوی حافظه را به هر پایگاه داده عامل منتقل کنید. انجام شد؛ memorySearch.store.path سفارشی صریح اکنون با مهاجرت پیکربندی doctor حذف می‌شود. بازنمایه‌سازی کامل فقط در محل و روی جدول‌های حافظه اجرا می‌شود؛ مسیر قدیمی تعویض کل فایل و کمک‌تابع تعویض نمایه جانبی حذف شده‌اند.
    • بازکننده‌های تکراری پایگاه داده، راه‌اندازی WAL، کمک‌تابع‌های مجوز و مسیرهای بستن را از آن زیرسامانه‌ها حذف کنید.
  3. جدول‌های متعلق به عامل را به پایگاه‌های داده به‌ازای هر عامل منتقل کنید.

    • پایگاه داده عامل را هنگام نیاز از طریق رجیستری پایگاه داده سراسری ایجاد کنید. انجام شد.
    • ورودی‌های نشست زمان اجرا، رویدادهای رونوشت، ردیف‌های VFS و مصنوعات ابزار را به پایگاه‌های داده عامل منتقل کنید. انجام شد.
    • ورودی‌های نشست پایگاه داده مشترک محلی شاخه، رویدادهای رونوشت، ردیف‌های VFS یا مصنوعات ابزار را مهاجرت ندهید؛ آن چیدمان هرگز منتشر نشد. فقط واردسازی قدیمی فایل به پایگاه داده را در doctor نگه دارید.
  4. APIهای ذخیره‌گاه نشست را جایگزین کنید.

    • storePath را به‌عنوان هویت زمان اجرا حذف کنید. برای زمان اجرا انجام شده و با check:database-first-legacy-stores محافظت می‌شود: فراداده نشست، به‌روزرسانی‌های مسیر، ماندگاری فرمان، پاک‌سازی نشست CLI، پیش‌نمایش‌های استدلال Feishu، ماندگاری وضعیت رونوشت، عمق زیرعامل، بازنویسی‌های نشست پروفایل احراز هویت، منطق انشعاب والد و بازرسی QA-lab اکنون پایگاه داده را از کلیدهای متعارف عامل/نشست تعیین می‌کنند. پاسخ‌های فهرست نشست Gateway/TUI/UI/macOS اکنون به‌جای path قدیمی، databasePath را ارائه می‌کنند؛ سطوح اشکال‌زدایی 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 APIهای SQLite-first هستند که به مسیر مخزن نشست نیاز ندارند. خلاصه وضعیت، وضعیت عامل محلی، سلامت، و فرمان فهرست‌کردن openclaw sessions اکنون ردیف‌های هر عامل را مستقیماً می‌خوانند و به‌جای مسیرهای sessions.json، مسیرهای پایگاه‌داده SQLite هر عامل را نمایش می‌دهند.
  • حذف/درج کل مخزن را با upsertSessionEntry، deleteSessionEntry، listSessionEntries و پرس‌وجوهای پاک‌سازی SQL جایگزین کنید. برای زمان اجرا انجام شد: مسیرهای داغ اکنون از APIهای ردیف و وصله‌های ردیف با تلاش مجدد هنگام تعارض استفاده می‌کنند؛ ابزارهای کمکی باقی‌مانده برای واردکردن/جایگزینی کل مخزن به کد واردکردن مهاجرت و آزمون‌های بک‌اند SQLite محدود شده‌اند.
    • store-writer.ts و آزمون‌های صف نویسنده را حذف کنید. انجام شد.
    • هرس کلیدهای قدیمی در زمان اجرا و پارامترهای حذف نام مستعار را از درج یا به‌روزرسانی/وصله‌کردن ردیف نشست حذف کنید. انجام شد.
  1. رفتار رجیستری JSON در زمان اجرا را حذف کنید.
    • خواندن و نوشتن رجیستری sandbox را فقط به SQLite محدود کنید. انجام شد.
    • JSON یکپارچه و شاردشده را فقط از مرحله مهاجرت وارد کنید. انجام شد.
    • قفل‌های رجیستری شاردشده و نوشتن JSON را حذف کنید. انجام شد.
  • اگر شکل داده همچنان وضعیت عملیاتی مسیر داغ است، به‌جای ذخیره‌سازی ردیف‌های رجیستری به‌صورت JSON مبهم عمومی، یک جدول رجیستری نوع‌دار نگه دارید. انجام شد.
  1. جهش نشست با ساختار قفل فایل را حذف کنید.

    • برای ایجاد قفل زمان اجرا و APIهای قفل زمان اجرا انجام شد.
    • مسیر پاک‌سازی مستقل و قدیمی .jsonl.lock در doctor حذف شده است.
    • یکپارچگی وضعیت دیگر مسیر جداگانه‌ای برای هرس فایل‌های رونوشت یتیم ندارد؛ مهاجرت doctor منابع قدیمی JSONL را در یک محل وارد و حذف می‌کند.
    • هماهنگی تک‌نمونه Gateway از ردیف‌های نوع‌دار SQLite در state_leases زیر gateway_locks استفاده می‌کند و دیگر درز دایرکتوری قفل فایل را در معرض استفاده قرار نمی‌دهد.
    • ماندگاری حذف موارد تکراری در SDK عمومی Plugin دیگر از قفل فایل یا فایل‌های JSON استفاده نمی‌کند؛ ردیف‌های وضعیت Plugin را در SQLite مشترک می‌نویسد. انجام شد.
    • هماهنگی QMD برای جاسازی‌ها از اجاره SQLite مشترک و برای هر نویسنده مجموعه/به‌روزرسانی/جاسازی از اجاره SQLite مختص هر عامل استفاده می‌کند. زمان اجرا دیگر qmd/embed.lock.lock یا agents/<agentId>/qmd-write.lock.lock را ایجاد نمی‌کند؛ Doctor فقط فایل‌های جانبی بازنشسته‌ای را حذف می‌کند که قطعاً منقضی شده‌اند. انجام شد.
  2. کارگرها را از پایگاه‌داده آگاه کنید.

    • کارگرها اتصال‌های SQLite خودشان را باز می‌کنند.
    • والد مالک تحویل، callbackهای کانال و پیکربندی است.
    • کارگر شناسه عامل، شناسه اجرا، حالت سیستم فایل و هویت رجیستری DB را دریافت می‌کند، نه handleهای زنده را.
    • vfs-only آزمایشی باقی می‌ماند و از پایگاه‌داده عامل به‌عنوان ریشه ذخیره‌سازی خود استفاده می‌کند.
    • در ابتدا برای هر اجرای فعال یک کارگر نگه دارید. تجمیع کارگرها می‌تواند تا زمانی که طول عمر اتصال DB و رفتار لغو کاملاً عادی و قابل‌پیش‌بینی شوند، منتظر بماند.
  3. یکپارچه‌سازی پشتیبان‌گیری.

    • به پشتیبان‌گیری بیاموزید از پایگاه‌های‌داده سراسری، عامل و Plugin با پشتیبان‌گیری آنلاین و سپس VACUUM آفلاین، snapshot بگیرد. برای فایل‌های کشف‌شده *.sqlite زیر دارایی وضعیت انجام شد؛ schemaهای Plugin که به قابلیت‌های مالکِ دردسترس‌نبودنی نیاز دارند، به‌صورت بسته شکست می‌خورند.
    • اعتبارسنجی پشتیبان را برای یکپارچگی SQLite متعارف و هویت schema، به‌همراه اعتبارسنجی عمومی شکل فایل برای snapshotهای اختصاصی Plugin اضافه کنید. برای ایجاد پشتیبان و اعتبارسنجی پیش‌فرض بایگانی انجام شد.
    • فراداده اجرای پشتیبان را در SQLite ثبت کنید. از طریق جدول مشترک backup_runs با مسیر بایگانی، وضعیت و JSON مانیفست انجام شد.
    • بازیابی از snapshotهای تأییدشده بایگانی را اضافه کنید. انجام شد: openclaw backup restore پیش از استخراج اعتبارسنجی می‌کند، از مانیفست نرمال‌شده اعتبارسنج استفاده می‌کند، از --dry-run پشتیبانی می‌کند و پیش از جایگزینی مسیرهای منبع ثبت‌شده به --yes نیاز دارد.
    • خروجی VFS/workspace را فقط هنگام درخواست شامل کنید؛ جزئیات داخلی نشست را به‌صورت JSON یا JSONL خروجی نگیرید.
  4. آزمون‌ها و کد منسوخ را حذف کنید. برای سطوح شناخته‌شده نشست در زمان اجرا انجام شد.

  • آزمون‌هایی را که ایجاد sessions.json یا فایل‌های JSONL رونوشت در زمان اجرا را بررسی می‌کنند، حذف کنید. برای مخزن اصلی نشست، گفت‌وگو، رویدادهای رونوشت Gateway، پیش‌نمایش، چرخه عمر، به‌روزرسانی‌های ورودی نشست فرمان، بازنشانی/ردیابی پاسخ خودکار و fixtureهای Dreaming در memory-core، مسیریابی مقصد تأیید، تعمیر رونوشت نشست، تعمیر مجوز امنیتی، خروجی trajectory و خروجی نشست انجام شد. آزمون‌های رونوشت Active Memory اکنون scopeهای SQLite و عدم ایجاد فایل JSONL موقت یا ماندگار را بررسی می‌کنند. رگرسیون قدیمی هرس رونوشت Heartbeat حذف شد، زیرا زمان اجرا دیگر رونوشت‌های JSONL را کوتاه نمی‌کند. آزمون‌های ابزار فهرست نشست عامل دیگر مسیرهای قدیمی sessions.json را به‌عنوان شکل پاسخ Gateway مدل نمی‌کنند؛ آزمون‌های برنامه/UI/macOS از databasePath استفاده می‌کنند. آزمون‌های استفاده از رونوشت /status اکنون به‌جای نوشتن فایل‌های JSONL، ردیف‌های رونوشت SQLite را مستقیماً مقداردهی اولیه می‌کنند. آزمون‌های چرخه عمر نشست Gateway اکنون مستقیماً از ابزارهای کمکی مقداردهی اولیه رونوشت SQLite استفاده می‌کنند؛ شکل قدیمی fixture فایل نشست تک‌خطی از پوشش بازنشانی و حذف کنار گذاشته شده است. sessions.delete دیگر فیلد دوران فایل archived: [] را برنمی‌گرداند؛ گزارش حذف فقط نتیجه جهش ردیف را ارائه می‌کند. گزینه قدیمی deleteTranscript نیز حذف شده است: حذف یک نشست، ریشه متعارف sessions را حذف می‌کند و به SQLite اجازه می‌دهد ردیف‌های رونوشت، snapshot و trajectory متعلق به نشست را به‌صورت آبشاری حذف کند؛ بنابراین هیچ فراخوانی‌کننده‌ای نمی‌تواند رونوشت یتیم باقی بگذارد یا شاخه پاک‌سازی را فراموش کند. آزمون‌های ثبت trajectory موتور زمینه اکنون ردیف‌های trajectory_runtime_events را از یک پایگاه‌داده عامل ایزوله می‌خوانند، نه از session.trajectory.jsonl. اسکریپت‌های مقداردهی اولیه کانال MCP در Docker اکنون ردیف‌های SQLite را مستقیماً مقداردهی می‌کنند. نوشتن مستقیم sessions.json به fixtureهای doctor محدود شده است. E2E مربوط به Tool Search Gateway شواهد فراخوانی ابزار را از ردیف‌های رونوشت SQLite می‌خواند، نه با اسکن فایل‌های agents/<agentId>/sessions/*.jsonl. رویدادهای میزبان memory-core و ردیف‌های موقت پیکره نشست اکنون در وضعیت Plugin مشترک SQLite قرار دارند؛ events.jsonl و session-corpus/*.txt فقط ورودی‌های قدیمی مهاجرت doctor هستند. ردیف‌های فعال از مسیرهای مجازی memory/session-ingestion/ استفاده می‌کنند، نه .dreams/session-corpus. ماژول قدیمی تعمیر Dreaming در memory-core و آزمون‌های CLI/Gateway آن حذف شدند، زیرا زمان اجرا دیگر مالک تعمیر بایگانی فایل برای آن پیکره نیست. آزمون‌های پل/مصنوع عمومی memory-core دیگر .dreams/events.jsonl را نمایش نمی‌دهند؛ آن‌ها از نام مصنوع مجازی JSON مبتنی بر SQLite استفاده می‌کنند. مستندات عمومی آزمون SDK/Codex اکنون به‌جای فایل‌های نشست، وضعیت نشست SQLite را بیان می‌کنند و مثال نوبت کانال دیگر آرگومان storePath را در معرض استفاده قرار نمی‌دهد. وضعیت همگام‌سازی Matrix اکنون مستقیماً از مخزن وضعیت Plugin در SQLite استفاده می‌کند. قراردادهای فعال کلاینت/زمان اجرا یک ریشه ذخیره‌سازی حساب را ارسال می‌کنند، نه مسیر bot-storage.json، و doctor پیش از حذف منبع، bot-storage.json قدیمی را به SQLite وارد می‌کند. سناریوهای راه‌اندازی مجدد/مخرب Matrix در QA Lab اکنون به‌جای ایجاد یا حذف فایل‌های جعلی bot-storage.json، مستقیماً ردیف همگام‌سازی SQLite را تغییر می‌دهند و زیرساخت E2EE به‌جای مسیر جعلی sync-store.json، ریشه مخزن همگام‌سازی را ارسال می‌کند. انتخاب ریشه ذخیره‌سازی Matrix دیگر ریشه‌ها را براساس فایل‌های قدیمی JSON همگام‌سازی/رشته امتیازدهی نمی‌کند؛ از فراداده ماندگار ریشه به‌همراه وضعیت واقعی رمزنگاری استفاده می‌کند. مجموعه آزمون بک‌اند نشست SQLite در زمان اجرا دیگر یک sessions.json جعلی نمی‌سازد؛ fixtureهای منبع قدیمی اکنون در آزمون‌های doctor که آن‌ها را وارد می‌کنند قرار دارند. آزمون‌های نشست Gateway دیگر ابزار کمکی createSessionStoreDir یا راه‌اندازی بلااستفاده مسیر موقت مخزن نشست را در معرض استفاده قرار نمی‌دهند؛ دایرکتوری‌های fixture صریح هستند و راه‌اندازی مستقیم ردیف از نام‌گذاری ردیف نشست SQLite استفاده می‌کند. پوشش parser مخزن نشست JSON5 مختص doctor از آزمون‌های زیرساخت خارج و به آزمون‌های مهاجرت doctor منتقل شد؛ بنابراین مجموعه آزمون‌های زمان اجرا دیگر مالک تجزیه فایل قدیمی نشست نیستند. آزمون‌های SSO/بارگذاری در انتظار در زمان اجرای Microsoft Teams دیگر fixtureها یا parserهای جانبی JSON را حمل نمی‌کنند؛ تجزیه توکن SSO قدیمی فقط در ماژول مهاجرت Plugin قرار دارد. آزمون‌های Telegram دیگر مسیرهای جعلی مخزن /tmp/*.json را مقداردهی اولیه نمی‌کنند؛ آن‌ها cache پیام مبتنی بر SQLite را مستقیماً بازنشانی می‌کنند. ابزار کمکی عمومی وضعیت آزمون OpenClaw دیگر نویسنده قدیمی auth-profiles.json را در معرض استفاده قرار نمی‌دهد؛ آزمون‌های مهاجرت احراز هویت doctor آن fixture را به‌صورت محلی در اختیار دارند. آزمون‌های زمان اجرا برای اشاره‌گرهای آخرین نشست TUI، تأییدهای exec، toggleهای Active Memory، حذف موارد تکراری/اعتبارسنجی راه‌اندازی Matrix، همگام‌سازی منبع Memory Wiki، اتصال‌های گفت‌وگوی جاری، احراز هویت onboarding و واردکردن secretهای Hermes دیگر فایل‌های جانبی قدیمی نمی‌سازند یا نبود نام فایل‌های قدیمی را بررسی نمی‌کنند. آن‌ها رفتار را از طریق ردیف‌های SQLite و APIهای عمومی مخزن اثبات می‌کنند؛ آزمون‌های doctor/مهاجرت تنها جایی هستند که نام فایل‌های منبع قدیمی به آن تعلق دارد. آزمون‌های زمان اجرا برای جفت‌سازی دستگاه/Node، allowFrom کانال، intentهای راه‌اندازی مجدد، handoff راه‌اندازی مجدد، ورودی‌های صف تحویل نشست، سلامت پیکربندی، cacheهای iMessage، کارهای Cron، سرآیندهای رونوشت PI، رجیستری‌های زیرعامل و پیوست‌های تصویر مدیریت‌شده نیز دیگر فایل‌های بازنشسته JSON/JSONL را فقط برای اثبات نادیده گرفته‌شدن یا نبودشان ایجاد نمی‌کنند. بازیابی سرریز PI دیگر fallback بازنویسی/کوتاه‌سازی SessionManager ندارد: کوتاه‌سازی نتیجه ابزار و بازنویسی‌های رونوشت موتور زمینه، ردیف‌های رونوشت SQLite را تغییر می‌دهند و سپس وضعیت فعال prompt را از پایگاه‌داده تازه‌سازی می‌کنند. افزودن پیام ماندگار SessionManager، انتخاب والد و idempotency را به ابزار کمکی اتمیک افزودن رونوشت SQLite واگذار می‌کند. افزودن ورودی عادی فراداده/سفارشی نیز والد جاری را درون SQLite انتخاب می‌کند؛ بنابراین نمونه‌های قدیمی manager رقابت‌های زنجیره والد پیش از SQLite را دوباره زنده نمی‌کنند. پاک‌سازی مصنوعی انتهای PI برای پیش‌بررسی‌های میان‌نوبت و sessions_yield اکنون وضعیت رونوشت SQLite را مستقیماً کوتاه می‌کند؛ پل قدیمی حذف انتهای SessionManager و آزمون‌های آن حذف شده‌اند. ثبت checkpoint در Compaction نیز فقط از SQLite snapshot می‌گیرد؛ فراخوانی‌کنندگان دیگر یک SessionManager زنده را به‌عنوان منبع جایگزین رونوشت ارسال نمی‌کنند.

  • آزمون‌هایی را که فایل‌های قدیمی را مقداردهی اولیه می‌کنند فقط برای مهاجرت نگه دارید.

  • برای سطوح فعال زمان اجرا، اثبات با فایل JSON با اثبات ردیف SQL جایگزین شده است.

  • ممنوعیت‌های ایستا برای نوشتن مسیرهای قدیمی JSON نشست/cache در زمان اجرا اضافه کنید. برای guard مخزن انجام شد.

  1. گزارش مهاجرت را قابل‌ممیزی کنید.
    • اجرای مهاجرت‌ها را با timestampهای شروع/پایان، مسیرهای منبع، hashهای منبع، تعدادها، هشدارها و مسیر پشتیبان در SQLite ثبت کنید. انجام شد: اجرای مهاجرت وضعیت قدیمی اکنون یک گزارش migration_runs با فهرست مسیر/جدول منبع، SHA-256 فایل منبع، اندازه‌ها، تعداد رکوردها، هشدارها و مسیر پشتیبان را ماندگار می‌کند. انجام شد: اجرای مهاجرت وضعیت قدیمی همچنین ردیف‌های migration_sources را برای ممیزی در سطح منبع و تصمیم‌های آینده درباره ردکردن/تکمیل سوابق ماندگار می‌کند.
    • اعمال را idempotent کنید. اجرای مجدد پس از واردکردن جزئی باید یا منبعی را که قبلاً وارد شده رد کند یا براساس کلید پایدار ادغام کند. انجام شد: indexهای نشست، رونوشت‌ها، صف‌های تحویل، وضعیت Plugin، دفترکل‌های وظیفه و ردیف‌های SQLite سراسری متعلق به عامل از طریق کلیدهای پایدار یا semantics درج یا به‌روزرسانی/جایگزینی وارد می‌شوند؛ بنابراین اجرای مجدد بدون تکرار ردیف‌های ماندگار ادغام می‌شود.
    • واردکردن ناموفق باید فایل منبع اصلی را در جای خود نگه دارد. انجام شد: واردکردن ناموفق رونوشت اکنون منبع اصلی JSONL را در مسیر شناسایی‌شده‌اش باقی می‌گذارد و migration_sources منبع را با وضعیت warning و removed_source=0 برای اجرای بعدی doctor ثبت می‌کند.

قواعد عملکرد

  • یک اتصال برای هر رشته/فرایند مناسب است؛ هندل‌ها را میان workerها به اشتراک نگذارید.
  • از WAL، foreign_keys=ON، مهلت انتظار مشغول‌بودن 5s و تراکنش‌های نوشتن کوتاه BEGIN IMMEDIATE استفاده کنید. تلاش‌های مجدد همگام برای قفل را روی انتظار منفرد مشغول‌بودن SQLite لایه‌بندی نکنید.
  • کمک‌تابع‌های تراکنش نوشتن را همگام نگه دارید، مگر/تا زمانی که یک API تراکنش ناهمگام معناشناسی صریح mutex/backpressure را اضافه کند.
  • نوشتن‌های تحویل والد را کوچک و تراکنشی نگه دارید.
  • از بازنویسی کل ذخیره‌گاه خودداری کنید؛ از upsert/delete در سطح ردیف استفاده کنید.
  • پیش از انتقال کد داغ، برای مسیرهای فهرست‌کردن بر اساس عامل، فهرست‌کردن بر اساس نشست، زمان به‌روزرسانی، شناسه اجرا و انقضا ایندکس اضافه کنید.
  • مصنوعات بزرگ، رسانه و بردارها را به‌صورت BLOB یا ردیف‌های BLOB قطعه‌بندی‌شده ذخیره کنید، نه JSON با base64 یا آرایه عددی.
  • ورودی‌های مبهم وضعیت Plugin را کوچک و محدود به دامنه نگه دارید.
  • به‌جای هرس سیستم فایل، پاک‌سازی SQL را برای TTL/انقضا اضافه کنید. این کار برای ذخیره‌گاه‌های زمان اجرای تحت مالکیت پایگاه داده انجام شده است: رسانه، وضعیت Plugin، blobهای Plugin، حذف تکرار پایدار و کش عامل، همگی از طریق ردیف‌های SQLite منقضی می‌شوند. پاک‌سازی باقی‌مانده سیستم فایل به مادی‌سازی‌های موقت یا فرمان‌های حذف صریح محدود است.

ممنوعیت‌های ایستا

یک بررسی مخزن اضافه کنید که نوشتن‌های جدید زمان اجرا در مسیرهای وضعیت قدیمی را ناموفق کند:

  • sessions.json
  • *.trajectory.jsonl به‌جز خروجی‌های مادی‌سازی‌شده بسته پشتیبانی
  • .acp-stream.jsonl
  • acp/event-ledger.json
  • فایل‌های کش زمان اجرای 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
  • openclaw-workspace-state.json
  • workspace-state.json
  • workspace-attestations/*.attested
  • <workspace>.attested هم‌سطح
  • 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 (بازنشسته‌شده در 2026.7: ذخیره‌گاه زمان اجرا device_pairing_* / device_bootstrap_tokens در پایگاه داده وضعیت مشترک است؛ رکوردهای جفت‌شده هنگام راه‌اندازی Gateway وارد می‌شوند و ردیف‌های موقت در انتظار/bootstrap حذف می‌شوند)
  • nodes/pending.json / nodes/paired.json (بازنشسته‌شده در 2026.7: هنگام راه‌اندازی Gateway در رکوردهای دستگاه جفت‌شده ادغام می‌شوند)
  • identity/device.json
  • identity/device-auth.json (بازنشسته‌شده؛ واردکردن فقط توسط Doctor به device_auth_tokens)
  • push/web-push-subscriptions.json (بازنشسته‌شده؛ واردکردن فقط توسط Doctor به web_push_subscriptions)
  • push/vapid-keys.json (بازنشسته‌شده؛ واردکردن فقط توسط Doctor به web_push_vapid_keys)
  • push/apns-registrations.json (بازنشسته‌شده؛ واردکردن فقط توسط Doctor به apns_registrations)
  • process-leases.json
  • gateway-instance-id
  • session-toggles.json
  • Memory-core .dreams/events.jsonl
  • Memory-core .dreams/session-corpus/
  • Memory-core .dreams/daily-ingestion.json
  • Memory-core .dreams/session-ingestion.json
  • Memory-core .dreams/short-term-recall.json
  • Memory-core .dreams/phase-signals.json
  • Memory-core .dreams/short-term-promotion.lock
  • Skill Workshop skill-workshop/<workspace>.json
  • Skill Workshop skill-workshop/skill-workshop-review-*.json
  • Nostr bus-state-*.json
  • Nostr profile-state-*.json
  • calls.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 شارد رجیستری sandbox
  • plugin-state/state.sqlite
  • sidecarهای زمان اجرای موردی 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.lock
  • agents/<agentId>/qmd-write.lock.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
  • openclaw/rescue-pending/*.json
  • plugins/phone-control/armed.json
  • Memory Wiki .openclaw-wiki/log.jsonl
  • Memory Wiki .openclaw-wiki/state.json
  • Memory Wiki .openclaw-wiki/locks/
  • Memory Wiki .openclaw-wiki/source-sync.json
  • Memory Wiki .openclaw-wiki/import-runs/*.json
  • Memory Wiki .openclaw-wiki/cache/agent-digest.json
  • Memory Wiki .openclaw-wiki/cache/claims.jsonl
  • ClawHub .clawhub/lock.json
  • ClawHub .clawhub/origin.json
  • تزئین پروفایل مرورگر .openclaw-profile-decorated
  • بازکننده‌های نشست مبتنی بر فایل SessionManager.open(...)
  • نماهای فهرست‌کردن رونوشت SessionManager.listAll(...) و TranscriptSessionManager.listAll(...)
  • نماهای انشعاب رونوشت SessionManager.forkFromSession(...) و TranscriptSessionManager.forkFromSession(...)
  • نماهای جایگزینی نشست تغییرپذیر SessionManager.newSession(...) و TranscriptSessionManager.newSession(...)
  • نماهای نشست شاخه‌ای SessionManager.createBranchedSession(...) و TranscriptSessionManager.createBranchedSession(...)

این ممنوعیت باید به آزمون‌ها اجازه دهد فیکسچرهای قدیمی ایجاد کنند و به کد مهاجرت اجازه دهد منابع فایل قدیمی را بخواند/وارد/حذف کند. sidecarهای SQLite منتشرنشده همچنان ممنوع می‌مانند و مجوز واردکردن توسط Doctor دریافت نمی‌کنند.

معیارهای انجام

  • نوشتن داده‌ها و کش زمان اجرا به پایگاه داده SQLite سراسری یا عامل انجام می‌شود.
  • زمان اجرا دیگر ایندکس‌های نشست، JSONL رونوشت، JSON رجیستری sandbox، SQLite جانبی وظیفه یا SQLite جانبی وضعیت Plugin را نمی‌نویسد. واردکننده‌های SQLite جانبی منتشرنشده وظیفه و وضعیت Plugin حذف شده‌اند.
  • واردکردن فایل قدیمی فقط توسط Doctor انجام می‌شود.
  • پشتیبان‌گیری یک بایگانی با snapshotهای فشرده SQLite و اثبات یکپارچگی تولید می‌کند.
  • workerهای عامل می‌توانند با دیسک، فضای موقت VFS یا ذخیره‌سازی آزمایشی فقط-VFS اجرا شوند.
  • فایل‌های پیکربندی و فایل‌های صریح اعتبارنامه، تنها فایل‌های کنترلی پایدار مورد انتظار خارج از پایگاه داده باقی می‌مانند.
  • بررسی‌های مخزن از معرفی دوباره ذخیره‌گاه‌های فایل زمان اجرای قدیمی جلوگیری می‌کنند.
Was this useful?
On this page

On this page