From 42fb58310cb8a3109a8e2d7b95c1a938a98a0a02 Mon Sep 17 00:00:00 2001 From: lix-2026 Date: Fri, 22 May 2026 19:31:20 +0800 Subject: [PATCH] chore: retire remaining convex infrastructure - move self-hosted Convex infra and root placeholder into recycle - update architecture docs to remove active infra/convex deployment guidance - extend local-first Convex guard to block retired infra regressions --- AGENTS.md | 6 +-- ARCHITECTURE.md | 4 +- REASONIX.md | 4 +- design/00-clean/2026-05-20-cleanup-summary.md | 5 +-- ...phase-sequential-execution-checklist-v1.md | 2 +- ...first-workspace-convex-control-plane-v1.md | 4 +- ...place-with-rust-sqlite-control-plane-v1.md | 4 +- ...acp-session-runtime-enhancement-plan-v1.md | 6 +-- .../done/03-convex-realtime-storage-review.md | 6 +-- .../infra}/convex/README.md | 0 .../infra}/convex/docker-compose.yml | 0 .../root/storage-convex-bridge | 0 scripts/check-local-first-convex-guard.js | 41 +++++++++++++++++++ 13 files changed, 61 insertions(+), 21 deletions(-) rename {infra => recycle/20260522-convex-runtime-retirement/infra}/convex/README.md (100%) rename {infra => recycle/20260522-convex-runtime-retirement/infra}/convex/docker-compose.yml (100%) rename storage-convex-bridge => recycle/20260522-convex-runtime-retirement/root/storage-convex-bridge (100%) diff --git a/AGENTS.md b/AGENTS.md index 3961dd31..c93abb6b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,8 +40,8 @@ Rust Web route、transport、compat、tree shell、projection 分发先看这里。 - `/mnt/Data1T/mnote/wolai-backend/app/` 辅助后端、异步处理、接口配合先看这里。 -- `/mnt/Data1T/mnote/infra/convex/` - Convex 自托管服务基础设施先看这里;只服务显式 cloud source / compat / sync replica 或历史数据导出,不再被 `desktop:hot` / `dev:hot` 默认启动链路要求。 +- `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/infra/convex/` + Convex 自托管服务基础设施已软删除到回收区;只作为显式 cloud source / compat / sync replica 或历史数据导出的历史对照,不再被 `desktop:hot` / `dev:hot` 默认启动链路要求。 - `/mnt/Data1T/mnote/src/components/onlyoffice/` 只在处理 OnlyOffice 静态资源、插件或兼容问题时进入。 - `/mnt/Data1T/mnote/recycle/` @@ -124,7 +124,7 @@ - 前端开发(已迁移至 Rust SSR):`npm run desktop:hot` 启动后直接访问 `http://localhost:3000` - 前端检查:Rust 测试 `cargo test -p mnote-web`(Rust SSR 与 API),旧 React 前端已移入 recycle - 后端开发:`cd /mnt/Data1T/mnote/wolai-backend && uvicorn app.main:app --reload --port 8000` -- Convex 自托管:仅在显式 cloud / compat / sync replica 或历史导出场景参考 `/mnt/Data1T/mnote/infra/convex/README.md` +- Convex 自托管:仅在显式 cloud / compat / sync replica 或历史导出场景参考 `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/infra/convex/README.md` ## 默认测试账号 diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 96c34730..7ad4f56b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -49,8 +49,8 @@ 根 `convex/` functions 源码已退役并软删除到这里;不再作为 active deploy source。历史 `schema.ts`、`aiSessions.ts`、Auth functions 仅用于审计 / 迁移对照,默认控制面已由 Rust SQLite control-plane 承接。 - `/mnt/Data1T/mnote/recycle/wolai-frontend/convex/` 已随 wolai-frontend 移入 recycle,不允许作为当前 Convex deploy fallback。 -- `/mnt/Data1T/mnote/infra/convex/` - Convex 自托管服务基础设施;只服务显式 cloud source / compat / sync replica 或历史数据导出,不再被 `desktop:hot` / `dev:hot` 默认启动链路要求。 +- `/mnt/Data1T/mnote/recycle/20260522-convex-runtime-retirement/infra/convex/` + Convex 自托管服务基础设施已软删除到回收区;只作为显式 cloud source / compat / sync replica 或历史数据导出的历史对照,不再被 `desktop:hot` / `dev:hot` 默认启动链路要求。 - `/mnt/Data1T/mnote/wolai-backend/` 辅助后端与异步处理,不是当前页面主链。 diff --git a/REASONIX.md b/REASONIX.md index 1143fccb..1d895765 100644 --- a/REASONIX.md +++ b/REASONIX.md @@ -27,7 +27,7 @@ | `rust/crates/mnote-cli/` | CLI tool (`sidebar dataset`, `page get/create/title/save/move`, `block insert/patch`) | | `rust/crates/storage-convex-bridge/` | Convex compat / cloud source / sync-replica bridge for Rust | | `recycle/20260522-convex-runtime-retirement/convex/` | Retired root Convex functions source retained for audit / migration reference | -| `infra/convex/` | Docker Compose for self-hosted Convex backend, used only for explicit cloud/compat/sync-replica paths | +| `recycle/20260522-convex-runtime-retirement/infra/convex/` | Retired self-hosted Convex backend compose kept only for historical cloud/compat/sync-replica reference | | `infra/onlyoffice/` | Docker Compose for OnlyOffice | | `scripts/` | Node.js dev/build scripts + Playwright smoke tests | | `design/` | Architecture design documents organized by domain | @@ -64,7 +64,7 @@ - **Local-first default**: start from Rust `mnote-web`, LocalFS/local_folder projection, Page Aggregate, File Tree, Resource Tree, and SQLite control-plane auth/session/actor. Use Convex paths only for explicit cloud source, compat, sync-replica, migration, or rollback work. - **Smoke test pattern**: standalone Playwright scripts under `scripts/task-*.js` using a shared harness (`ensureAuthenticated`, `createTempDocument`, `cleanupDocuments`). All use `"use strict"` and `require("playwright")` (`scripts/task110-page-title-single-truth-smoke.js:1-4`). - **Rust workspace**: edition 2021, resolver "2", MIT license. All crates inherit workspace version (`rust/Cargo.toml:2-8`). -- **Convex boundary**: root `convex/` has been retired to `recycle/20260522-convex-runtime-retirement/convex/`; do not recreate it as an active deploy source without a new architecture decision. `recycle/wolai-frontend/convex` is also historical. Keep Rust `transport/convex.rs` and `storage-convex-bridge` as explicit cloud/compat boundaries; do not mechanically delete them with the retired functions source. +- **Convex boundary**: root `convex/` has been retired to `recycle/20260522-convex-runtime-retirement/convex/`; `infra/convex/` has been retired to `recycle/20260522-convex-runtime-retirement/infra/convex/`; do not recreate either as an active deploy source without a new architecture decision. `recycle/wolai-frontend/convex` is also historical. Keep Rust `transport/convex.rs` and `storage-convex-bridge` as explicit cloud/compat boundaries; do not mechanically delete them with the retired functions source. - **AI editing path**: local-first Markdown editing should prefer `currentFile + selection + allowedRoots / aiAccessScope + agent native patch/diff + watcher sync`. `mnote.doc.*` / `mnote.block.*` are cloud, remote, compat, or complex-structure helpers. - **Bug tracking**: bugs organized by design domain directory (e.g. `bugs/04-tree-domain/process/`), moved to `done/` when fixed (`bugs/README.md`). - **Design docs**: organized by domain in `design/`, with `process/` (in-progress) and `done/` (completed) subdirs (`design/README.md`). diff --git a/design/00-clean/2026-05-20-cleanup-summary.md b/design/00-clean/2026-05-20-cleanup-summary.md index c7b69706..294f6d7c 100644 --- a/design/00-clean/2026-05-20-cleanup-summary.md +++ b/design/00-clean/2026-05-20-cleanup-summary.md @@ -55,7 +55,7 @@ codegraph status 已更新说明: -- `infra/convex/README.md` +- `recycle/20260522-convex-runtime-retirement/infra/convex/README.md` - `AGENTS.md` - `REASONIX.md` @@ -104,7 +104,7 @@ npm ls --depth=0 --json - `home/` - `.sandbox-home` - `.sandbox-tmp` -- `.convex-tmp` +- `recycle/20260522-convex-runtime-retirement/local-state/.convex-tmp` 当前该回收目录体积约 `912K`。 @@ -230,4 +230,3 @@ find -L node_modules -maxdepth 2 -type l -printf 'BROKEN %p -> %l\n' - 不从 `recycle` 中回退引用运行时代码。 - 新增 CodeGraph 主索引排除项时,应优先判断其是否属于参考代码、生成缓存、测试输出、回收区或本地辅助功能。 - 后续依赖变化后应重新运行 `pnpm install`,CodeGraph 在代码变化后需要重建或等待 watcher 更新;若排除规则变化,需显式重新初始化 / 重建索引。 - diff --git a/design/01-tree-first-graph-kernel/process/1-5-next-phase-sequential-execution-checklist-v1.md b/design/01-tree-first-graph-kernel/process/1-5-next-phase-sequential-execution-checklist-v1.md index a1aaaf74..69abb8a1 100644 --- a/design/01-tree-first-graph-kernel/process/1-5-next-phase-sequential-execution-checklist-v1.md +++ b/design/01-tree-first-graph-kernel/process/1-5-next-phase-sequential-execution-checklist-v1.md @@ -530,7 +530,7 @@ - `rust/crates/mnote-web/src/routes/local_access_policy.rs` - `rust/crates/mnote-web/src/routes/hermes_client.rs` - `rust/crates/core-protocol/src/ai.rs` -- `infra/convex/` +- `recycle/20260522-convex-runtime-retirement/infra/convex/`(历史 Convex 自托管对照;不作为 active 部署入口) ### 9.2 参考代码位置 diff --git a/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md b/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md index 367b5722..9611b901 100644 --- a/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md +++ b/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md @@ -1040,9 +1040,9 @@ local-first 下,AI 的长期主路径不是继续发明一套 MNote 专用编 #### G. 控制面收口与旧数据迁移 - [x] G1. 历史 Convex 控制面字段边界冻结;当前默认控制面已替换为 SQLite。 - - 文件:`infra/convex/`、`rust/crates/mnote-web/src/transport/convex.rs`。 + - 文件:`recycle/20260522-convex-runtime-retirement/infra/convex/`、`rust/crates/mnote-web/src/transport/convex.rs`。 - 完成定义:新增 Convex 调用只能属于显式 cloud source、compat、migration 或 sync replica;默认 auth、membership、share grants、sync state、AI policy、ACP/Hermes runtime session 走 Rust SQLite control-plane。 - - 完成证据:`infra/convex/README.md` 与 `docker-compose.yml` 已明确 Convex 自托管仅作为显式 cloud source / compat / sync replica 或历史数据导出;`transport/convex.rs` 保留为 cloud/compat transport 边界;`scripts/check-local-first-convex-guard.js --self-test` 已通过,并新增 active `convex/` 目录防重新引入未标注 documents/media 主存储表或函数。 + - 完成证据:`recycle/20260522-convex-runtime-retirement/infra/convex/README.md` 与 `docker-compose.yml` 已明确 Convex 自托管仅作为显式 cloud source / compat / sync replica 或历史数据导出;`transport/convex.rs` 保留为 cloud/compat transport 边界;`scripts/check-local-first-convex-guard.js --self-test` 已通过,并新增 active `convex/` 与 `infra/convex` 退役目录回流拦截,防重新引入未标注 documents/media 主存储表或函数。 - [x] G2. 旧 Convex workspace 导出为 local workspace。 - 文件:新增迁移脚本,优先放 `scripts/` 或 `tools/`。 - 验证:fixture workspace 导出后包含 `.md`、assets、`.mnote/page-ids.json`。 diff --git a/design/02-convex-rust-long-term-architecture/done/2-8-convex-replace-with-rust-sqlite-control-plane-v1.md b/design/02-convex-rust-long-term-architecture/done/2-8-convex-replace-with-rust-sqlite-control-plane-v1.md index 6ea76d2b..f92b425a 100644 --- a/design/02-convex-rust-long-term-architecture/done/2-8-convex-replace-with-rust-sqlite-control-plane-v1.md +++ b/design/02-convex-rust-long-term-architecture/done/2-8-convex-replace-with-rust-sqlite-control-plane-v1.md @@ -790,7 +790,7 @@ Ownership: - [x] `/api/realtime/ws` 能收到控制面事件。 - [x] AI allowed roots 不扩大到未授权目录。 - [x] `NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:9` 时 local-first 主路径 smoke 通过。 -- [x] `infra/convex` 不再被 `npm run desktop:hot` 或默认启动链路要求。 +- [x] `infra/convex` 已软删除到 `recycle/20260522-convex-runtime-retirement/infra/convex/`,不再被 `npm run desktop:hot` 或默认启动链路要求。 - [x] 根 `convex/` functions 源码已软删除到 `recycle/20260522-convex-runtime-retirement/convex/`,`scripts/run-convex-deploy.js` 已随之归档。 - [x] `package.json` / npm lock / pnpm lock 已移除只服务根 Convex functions 的 `@auth/core`、`@convex-dev/auth`、`convex` 依赖。 - [x] 文档更新,明确 Convex 只作为历史迁移源或显式 legacy 兼容入口。 @@ -850,6 +850,6 @@ Ownership: - 根 `convex/` 已按软删除规则移动到 `recycle/20260522-convex-runtime-retirement/convex/`,只作为历史审计 / 迁移对照素材。 - `scripts/run-convex-deploy.js` 已移动到 `recycle/20260522-convex-runtime-retirement/scripts/run-convex-deploy.js`;默认仓库不再提供根 Convex functions deploy 入口。 - `package.json`、`package-lock.json`、`pnpm-lock.yaml` 已移除只服务根 Convex functions 的 `@auth/core`、`@convex-dev/auth`、`convex` 依赖。 - - `npm run desktop:hot` 与 `npm run dev:hot` 均已确认只启动 Rust `mnote-web` hot 链路,不启动 Convex;`infra/convex` 仍保留为显式 cloud / compat / sync replica 服务基础设施。 + - `npm run desktop:hot` 与 `npm run dev:hot` 均已确认只启动 Rust `mnote-web` hot 链路,不启动 Convex;`infra/convex` 已软删除到 `recycle/20260522-convex-runtime-retirement/infra/convex/`,只作为历史对照,不再作为默认启动链路或 active 服务基础设施。 - `gateway.rs` 已移除旧 Convex Auth action proxy / username lookup / auth response cookie helper,默认 `/api/auth` 只走 SQLite session。 - `scripts/check-local-first-convex-guard.js` 更新为拦截重新新增根 `convex/schema.ts`、`auth.ts`、`users.ts`、`aiSessions.ts`,防止退役 functions 源码回流默认控制面。 diff --git a/design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md b/design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md index e9c59f30..2d9fe843 100644 --- a/design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md +++ b/design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md @@ -163,7 +163,7 @@ 当前仓库状态下: -- `infra/convex/` 只承载自托管 Convex backend/dashboard 的 Docker 与说明,不是 functions/schema 源目录; +- `recycle/20260522-convex-runtime-retirement/infra/convex/` 只保留自托管 Convex backend/dashboard 的 Docker 与说明作为历史对照,不是 functions/schema 源目录; - `wolai-frontend/convex/` 已不在当前工作区可读路径中,不能作为新的实现落点; - `recycle/wolai-frontend/convex/` 只作为历史参考; - 本轮历史执行曾在仓库根 `convex/` 建立 ACP-local runtime store 的最小 functions/schema,并让 `scripts/run-convex-deploy.js` 优先以仓库根作为 Convex CLI cwd;当前这些源码和脚本已退役到 `recycle/20260522-convex-runtime-retirement/`。 @@ -210,7 +210,7 @@ struct MessageRow { ### 4.2 现有代码改动范围 -- **历史项**:曾新增/修改根 `convex/` 相关 schema / functions,承接 ACP-local session/runtime 记录、用户隔离查询、TTL 清理;当前默认应改 Rust SQLite control-plane schema/API,`infra/convex/` 只负责显式 cloud / compat 服务部署 +- **历史项**:曾新增/修改根 `convex/` 相关 schema / functions,承接 ACP-local session/runtime 记录、用户隔离查询、TTL 清理;当前默认应改 Rust SQLite control-plane schema/API,`infra/convex/` 已软删除到 recycle,只负责历史对照,不再作为 active 服务部署 - **修改** `acp_session_manager.rs` — 按架构决策写入 ACP-local 消息或只写 runtime/event 索引 - **修改** `hermes_client.rs` — 新增 session 管理 route handlers - **修改** `routes/mod.rs` — 注册新 route @@ -359,7 +359,7 @@ Phase C(P2 用户体验) - `node scripts/run-convex-deploy.js`:历史验证通过;当时部署入口已避免用根最小 `convex/` 覆盖完整本地 Convex schema。当前默认启动链路不再部署 Convex。 - `node` 提取并 `new Function(SIDEBAR_TREE_JS)`:通过。 - `npx convex --version`:1.39.1。 - - `CONVEX_TMPDIR=/mnt/Data1T/mnote/.convex-tmp npx convex codegen --dry-run --typecheck try`:通过。 + - 历史验证:`CONVEX_TMPDIR=/mnt/Data1T/mnote/.convex-tmp npx convex codegen --dry-run --typecheck try` 曾通过;当前 `.convex-tmp` 已软删除到 `recycle/20260522-convex-runtime-retirement/local-state/.convex-tmp`,不再作为 active codegen 临时目录。 - Playwright browser smoke:`127.0.0.1:3000` 页面内 fetch 创建两个用户的 ACP session,并验证 list/detail/resume/rename/delete 与用户隔离,全部通过;测试数据已调用 delete 清理。 - 回归收口:`tree_command_purge_uses_tree_command_protocol` 中 purge 请求未携带排序,返回 `sortOrder: null` 符合当前 route 语义,已同步修正测试断言。 - 回归收口:`hermes_client` / `hermes_tools` / `page_ai_workflow` 测试统一使用 crate 级 Hermes 环境锁,避免完整并发测试时互相修改 `HERMES_HOME` / `MNOTE_WEB_HERMES_*`。 diff --git a/design/10-review/done/03-convex-realtime-storage-review.md b/design/10-review/done/03-convex-realtime-storage-review.md index 36845f4a..d125f0df 100644 --- a/design/10-review/done/03-convex-realtime-storage-review.md +++ b/design/10-review/done/03-convex-realtime-storage-review.md @@ -21,7 +21,7 @@ - `design/05-editor-mainline/process/5-5-page-aggregate-single-truth-alignment-v1.md` - `design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md` - `design/05-editor-mainline/done/5-5-1-page-aggregate-contract-v1.md` -- `infra/convex/README.md` +- `recycle/20260522-convex-runtime-retirement/infra/convex/README.md` - `wolai-frontend/convex/` - `rust/crates/storage-convex-bridge/` - `rust/crates/mnote-web/src/transport/convex.rs` @@ -36,7 +36,7 @@ 整体方向与设计主线基本一致:Convex 没有被拆掉,仍承担本地自托管存储、文件和实时底座;Rust Web 已注册 `/api/page-aggregate/:document_id` 与 `/api/tree/events`;前端 tree stream 已直接使用 `EventSource("/api/tree/events")`;Next 的 `/api/documents/page` 与 `/api/mnote-web/stream` 已明确作为 410 compat 边界退场。 -但当前实现仍是明显过渡态,主要问题集中在三处: +但当前实现仍是明显过渡态,主要问题集中在三处;本文里的 `infra/convex` 现在应按历史对照理解,因为自托管 compose 已软删除到 recycle,不再作为 active 部署入口: 1. Page Aggregate 读链虽然是 Rust endpoint,但实际数据仍由 `documents:getMeta` + `documents:getContent` 分别取回后在 bridge-runtime 中拼 projection,`source` 标识存在“看起来比真实实现更 canonical”的风险。 2. Rust Web 的 `/api/documents/title`、`/api/documents/options` 与 Next route 的 page write adapter 在 bridge artifact 记录上不一致;tree stream 依赖 bridgeLogs 时,Rust page write 路径可能漏掉 command/domain event。 @@ -155,7 +155,7 @@ tree command route 是一致的: 正向证据: -- `infra/convex/README.md` 明确自托管 Convex backend/dashboard、HTTP Actions 和文件存储。 +- `recycle/20260522-convex-runtime-retirement/infra/convex/README.md` 明确自托管 Convex backend/dashboard、HTTP Actions 和文件存储的历史对照口径。 - `wolai-frontend/convex/schema.ts:35` 到 `:91` 的 `documents` 表继续承接页面结构、正文、页面设置、统计字段。 - `wolai-frontend/convex/schema.ts:121` 到 `:162` 的 `media_assets` 与 `_storage` 字段保留文件底座。 - `rust/crates/storage-convex-bridge/README.md:5` 到 `:13` 明确 bridge 只做协议到 Convex 读写请求映射,不复制主事实层、不维护第二数据库。 diff --git a/infra/convex/README.md b/recycle/20260522-convex-runtime-retirement/infra/convex/README.md similarity index 100% rename from infra/convex/README.md rename to recycle/20260522-convex-runtime-retirement/infra/convex/README.md diff --git a/infra/convex/docker-compose.yml b/recycle/20260522-convex-runtime-retirement/infra/convex/docker-compose.yml similarity index 100% rename from infra/convex/docker-compose.yml rename to recycle/20260522-convex-runtime-retirement/infra/convex/docker-compose.yml diff --git a/storage-convex-bridge b/recycle/20260522-convex-runtime-retirement/root/storage-convex-bridge similarity index 100% rename from storage-convex-bridge rename to recycle/20260522-convex-runtime-retirement/root/storage-convex-bridge diff --git a/scripts/check-local-first-convex-guard.js b/scripts/check-local-first-convex-guard.js index cfd448b7..113e5c4e 100644 --- a/scripts/check-local-first-convex-guard.js +++ b/scripts/check-local-first-convex-guard.js @@ -69,6 +69,17 @@ const RETIRED_ROOT_CONVEX_PATHS = [ }, ]; +const RETIRED_CONVEX_INFRA_PATHS = [ + { + name: "Convex 自托管 infra", + pattern: /^infra\/convex(?:\/|$)/, + }, + { + name: "根 storage-convex-bridge 占位文件", + pattern: /^storage-convex-bridge$/, + }, +]; + // ─── SQLite 迁移期 forbid ─────────────────────────────────── // 在 SQLite 控制面迁移阶段(Phase 1-5),新增 Convex 控制面代码 // (users/workspaces/sessions/policies/audit/outbox/share 等) @@ -122,6 +133,7 @@ function usage() { "", `如需保留明确的 cloud/compat 直连,请在同一新增行加入 ${WAIVER}。`, "根 convex/ functions 源码已退役;如确需新增显式 cloud/compat Convex functions,应先放到明确的辅助目录并更新 guard。", + "infra/convex 自托管基础设施已退役到 recycle;不要重新引回 active 路径。", `SQLite 迁移期中新增 Convex 控制面代码(users/workspaces/grants/share 等)需加 ${MIGRATION_PERIOD_WAIVER} 标注迁移例外。`, ].join("\n"); } @@ -179,6 +191,10 @@ function isRetiredRootConvexPath(filePath) { return RETIRED_ROOT_CONVEX_PATHS.some((entry) => entry.pattern.test(filePath)); } +function isRetiredConvexInfraPath(filePath) { + return RETIRED_CONVEX_INFRA_PATHS.some((entry) => entry.pattern.test(filePath)); +} + function isAllowedRuntimeAdapter(filePath) { return ( filePath === "rust/crates/mnote-web/src/transport/convex.rs" || @@ -280,6 +296,15 @@ function checkLine(row) { ]; } + if (isRetiredConvexInfraPath(row.filePath)) { + return [ + { + ...row, + reason: `${RETIRED_CONVEX_INFRA_PATHS.find((entry) => entry.pattern.test(row.filePath)).name} 已软删除到 recycle;不要重新引回 active 路径或默认启动链路。`, + }, + ]; + } + if (!isRuntimePath(row.filePath) || isAllowedRuntimeAdapter(row.filePath)) { if (!isActiveConvexPath(row.filePath)) { return []; @@ -347,6 +372,16 @@ function runSelfTest() { lineNumber: 1, text: " workspaces: defineTable({", }, + { + filePath: "infra/convex/docker-compose.yml", + lineNumber: 1, + text: "services:", + }, + { + filePath: "storage-convex-bridge", + lineNumber: 1, + text: "", + }, ]; const violations = rows.flatMap(checkLine); const labels = violations.map((item) => item.filePath); @@ -374,6 +409,12 @@ function runSelfTest() { if (!labels.includes("convex/workspaces_migration.ts")) { throw new Error("self-test 失败:未拦截迁移期新增 Convex 控制面 workspaces 代码"); } + if (!labels.includes("infra/convex/docker-compose.yml")) { + throw new Error("self-test 失败:未拦截退役的 Convex infra 回流"); + } + if (!labels.includes("storage-convex-bridge")) { + throw new Error("self-test 失败:未拦截根 storage-convex-bridge 占位文件回流"); + } console.log(JSON.stringify({ ok: true, guard: "local-first-convex", selfTest: true }, null, 2)); }