diff --git a/README.md b/README.md index c73b480..172519c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ - 生成验证进程清理计划:按项目路径和端口给出 PowerShell 检查命令,不直接杀进程。 - 清理历史产物:统一治理 `.kt-workspace` 下的测试/验证产物,按目录最近修改时间只保留最近 3 轮,模板目录永久保留;CLI 默认 dry-run,真实清理必须显式传 `--execute`。 - 检查 env 策略和变更风险:区分后端真实 env 与前端客户端 `.env*`,提醒锁文件、核心表格组件、API 时间序列化 KtDateTime 列/DTO 装饰器入口、部署链路和 Vue TSX 插槽写法等高风险改动。 -- 全局 CodeReview 只读扫描:汇总全部 KT 子仓库的 Git 状态、敏感文件跟踪、冲突标记、运行时调试输出、疑似凭据字面量、NapCat `latest` 镜像漂移风险、QQBot 重型服务单测导入风险、QQBot 插件 registry/controller smoke 未 mock 具体插件实现风险、QQBot OneBot/QQ 登录态边界回归、NapCat 密码登录验证码 wait 阶段、日志窗口锚点、验证码状态早于日志 URL 的短轮询、验证码 pending 被状态轮询误清理、API Pod SSH 日志读取超时和清理前 pending 回归、普通处理中状态误吃旧验证码日志回归、根目录生成产物、`TASKS.md` 最近记录字段结构和当前变更风险;默认只对变更文件做内容扫描,并放过短中文显示标签和明显测试占位 token,避免历史误报污染上下文;任何文件改动后都要跑一遍。 +- 全局 CodeReview 只读扫描:汇总全部 KT 子仓库的 Git 状态、敏感文件跟踪、冲突标记、运行时调试输出、疑似凭据字面量、NapCat `latest` 镜像漂移风险、QQBot 重型服务单测导入风险、QQBot 插件 registry/controller smoke 未 mock 具体插件实现风险、QQBot OneBot/QQ 登录态边界回归、NapCat 密码登录验证码 wait 阶段、日志窗口锚点、验证码状态早于日志 URL 的短轮询、验证码 pending 被状态轮询误清理、API Pod SSH 日志读取超时和清理前 pending 回归、普通处理中状态误吃旧验证码日志回归、根目录生成产物、`TASKS.md` 最近记录字段结构、最近记录 3 条上限和当前变更风险;默认只对变更文件做内容扫描,并放过短中文显示标签和明显测试占位 token,避免历史误报污染上下文;任何文件改动后都要跑一遍。 - 生成或写入 `TASKS.md` 最近记录:默认 `dryRun=true`,确认后再落盘。 - 生成提交前检查清单:校验 KT commit message 约定。 @@ -134,7 +134,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login | 脚本 | 用途 | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `pnpm run admin-login` | 使用可见 Edge 打开 Admin 登录页,填写账号密码,拖动滑块,保存登录态和截图。默认账号来自初始化数据 `admin/123456`,生产或个人账号用 `KT_ADMIN_USERNAME` / `KT_ADMIN_PASSWORD` 或 CLI 参数覆盖。 | -| `pnpm run global-review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅对变更文件做内容深扫,输出 JSON 复审报告,并校验 `TASKS.md` 最近记录只保留范围、关键词、验证字段、NapCat `latest` 漂移、QQBot 重型服务单测导入风险、QQBot 插件 registry/controller smoke 未 mock 具体插件实现风险、OneBot/QQ 登录态边界、NapCat 密码登录验证码 wait 阶段、日志窗口锚点、验证码状态早于日志 URL 的短轮询、验证码 pending 被状态轮询误清理、API Pod SSH 日志读取超时及清理前 pending 回归,以及普通处理中状态误吃旧验证码日志回归;明显测试占位 token 不报凭据风险,确认误报时优先升级 `src/tools/review.ts`,不要把误报沉积到上下文。 | +| `pnpm run global-review` | 对 KT 全部子仓库做只读全局 CodeReview 扫描,默认仅对变更文件做内容深扫,输出 JSON 复审报告,并校验 `TASKS.md` 最近记录只保留最新 3 条详细记录,以及每条记录只保留范围、关键词、验证字段;同时校验 NapCat `latest` 漂移、QQBot 重型服务单测导入风险、QQBot 插件 registry/controller smoke 未 mock 具体插件实现风险、OneBot/QQ 登录态边界、NapCat 密码登录验证码 wait 阶段、日志窗口锚点、验证码状态早于日志 URL 的短轮询、验证码 pending 被状态轮询误清理、API Pod SSH 日志读取超时及清理前 pending 回归,以及普通处理中状态误吃旧验证码日志回归;明显测试占位 token 不报凭据风险,确认误报时优先升级 `src/tools/review.ts`,不要把误报沉积到上下文。 | | `pnpm run napcat-upstream-audit` | 默认 dry-run 输出 NapCatQQ 上游 release 审计分类、只读 Git 命令和 artifact 路径;显式 `--execute --use-codex` 才运行 Codex。 | | `pnpm run napcat-sync-candidate-review` | 输出 sync candidate review 的 prompt/context/只读命令骨架,不执行 Codex 或 Git 写操作。 | | `pnpm run napcat-runtime-release-readiness` | 输出 runtime release readiness 的 prompt/context/只读检查骨架,不构建镜像、不调用 kubectl、不发布。 | diff --git a/src/selfTest.ts b/src/selfTest.ts index 4e31e6d..30375de 100644 --- a/src/selfTest.ts +++ b/src/selfTest.ts @@ -1122,6 +1122,33 @@ export async function runSelfTest(): Promise { ) { throw new Error("TASKS record governance self-check failed"); } + const taskRecordLimitFindings = findTaskRecordGovernanceFindings([ + "## 最近记录", + "### 2026-06-13:记录一", + "- 范围:root", + "- 关键词:TASKS 治理", + "- 验证:global-review", + "### 2026-06-12:记录二", + "- 范围:root", + "- 关键词:TASKS 治理", + "- 验证:global-review", + "### 2026-06-11:记录三", + "- 范围:root", + "- 关键词:TASKS 治理", + "- 验证:global-review", + "### 2026-06-10:记录四", + "- 范围:root", + "- 关键词:TASKS 治理", + "- 验证:global-review", + "## 历史索引", + ]); + if ( + !taskRecordLimitFindings.some( + (item) => item.category === "tasks-recent-record-limit", + ) + ) { + throw new Error("TASKS recent record limit self-check failed"); + } const napcatImageFindings = findNapcatImageGovernanceFindings( ["QQBOT_NAPCAT_IMAGE=mlikiowa/napcat-docker:latest"], diff --git a/src/tools/review.ts b/src/tools/review.ts index 02e1484..c3ce3b6 100644 --- a/src/tools/review.ts +++ b/src/tools/review.ts @@ -68,6 +68,7 @@ const napcatImageAssignmentPattern = /^\s*QQBOT_NAPCAT_IMAGE\s*=\s*([^#\s]+)\s*(?:#.*)?$/; const taskRecordAllowedFields = new Set(["范围", "关键词", "验证"]); const taskRecordRequiredFields = ["范围", "关键词", "验证"] as const; +const taskRecentRecordLimit = 3; interface ReviewFinding { category: string; @@ -92,6 +93,11 @@ interface ReviewProjectResult { trackedSensitiveFiles: string[]; } +/** + * Checks the root task index for compact recent-record governance. + * @param lines - Current `TASKS.md` content split by line, used to inspect the `## 最近记录` section without rereading files. + * @returns Review findings for missing fields, extra fields, or too many detailed recent task records. + */ export function findTaskRecordGovernanceFindings( lines: string[], ): ReviewFinding[] { @@ -104,6 +110,22 @@ export function findTaskRecordGovernanceFindings( .findIndex((line) => /^##\s+/.test(line.trim())); const recentEnd = nextSectionOffset < 0 ? lines.length : recentStart + 1 + nextSectionOffset; + const recordHeadings = lines + .slice(recentStart + 1, recentEnd) + .map((line, offset) => ({ line, lineNumber: recentStart + 2 + offset })) + .filter((item) => item.line.trim().startsWith("### ")); + if (recordHeadings.length > taskRecentRecordLimit) { + findings.push({ + category: "tasks-recent-record-limit", + file: "TASKS.md", + line: recordHeadings[taskRecentRecordLimit]?.lineNumber, + level: "P2", + message: `TASKS 最近记录只允许保留 ${taskRecentRecordLimit} 条详细记录,当前为 ${recordHeadings.length} 条。`, + project: "root", + suggestion: + "保留最新 3 条详细记录,其余迁入「历史索引」的关键词条目。", + }); + } let currentRecord: { fields: Set; heading: string;