diff --git a/README.md b/README.md index 613685d..7fa2777 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ - 生成页面测试用例:内置“先写用例、可视化证据、事不过三”的测试闭环。 - 生成接口测试计划:接口改动后输出真实调用命令和统一返回结构断言。 - 生成业务链路测试计划:固化 Admin 登录、博客 CRUD、QQBot 扫码/自动回复、更新登录 SSE、FFLogs 命令、系统日志可视化、Web/Playground 回跳。 -- 静态检查 NapCat 设备身份护栏:确认 API 仍保留 QQNT 可见 hostname、稳定 `02:42:*` MAC、QQNT `machine-info` 写入、持久化 runtime dir 和 `DB_TIMEZONE` 默认值。 +- 静态检查 NapCat 设备身份护栏:确认 API 仍保留 QQNT 可见 hostname、实体 OUI 风格 MAC、QQNT `machine-info` 写入、持久化 runtime dir 和 `DB_TIMEZONE` 默认值。 - 生成卡点固化记录:把超时、卡进程、远程命令误写、重复失败整理成“问题点 / 稳定解法 / 后续入口 / 验证证据”,避免原样重试。 - 生成改动文档同步计划:按变更文件自动提示需要同步的 README、API、AGENTS、docs、Obsidian、skill 和 ktWorkflow 入口。 - 生成多仓库提交/推送计划:按仓库分组、建议提交信息、列出提交和推送前检查。 @@ -154,6 +154,7 @@ pnpm run admin-login -- --url http://127.0.0.1:5999/#/auth/login - 大方向结束前调用 `kt_workstream_closeout` 或 `pnpm run workstream-closeout`;必须分别传入 `--review` 的 KT 全局审查证据和 `--superpowers-review` 的 Superpowers code review 证据;如果识别到测试流、卡点、误报、清理、部署观测或命令模板,要先升级对应 ktWorkflow 规则再报告完成。 - 文件改动完成并验证后调用 `kt_global_code_review`,或运行 `pnpm run global-review`;它只读扫描,不删除文件、不提交代码。`findings` 先判定真实风险或工具误报,真实风险修业务代码,误报修 `mcp/ktWorkflow/src/tools/review.ts` 并复跑。 - QQBot NapCat 登录 review 会检查验证码 pending、Docker 日志窗口、API Pod 读取超时,以及 `needNewDevice/jumpUrl` 是否进入 `GetNewDeviceQRCode -> PollNewDeviceQR -> NewDeviceLogin` 或兼容的 `deviceVerifyUrl` pending 状态。 +- QQBot NapCat 二维码刷新卡在生成阶段时,优先计数当前容器近 5-20 分钟日志里的“重置已失效登录服务后重新生成二维码”、`Login Error,ErrType: 7 ErrCode: 4` 和“二维码已保存/二维码解码URL”;如果 reset/error 数远高于二维码产出,按 `docs/qqbot-nas-runtime.md` 的 v5 稳定解法排查 NapCat native login service reset 风暴,先修 fork/镜像,再看 API SSE。 - 代码或配置改动后调用 `kt_change_doc_sync`,把需要同步的 README/API/AGENTS/docs/Obsidian/skill/ktWorkflow 入口补齐;无需同步时把原因写进收尾证据。 - 报告非平凡任务完成前调用 `kt_workflow_loop_audit`,确认测试证据、文档同步、历史清理最终 `deleted=0`、问题固化、ktWorkflow 升级、KT 全局 review 和 Superpowers code review 都过门;清理证据必须显式传入,不能依赖缺省值。 - 要提交或推送时先调用 `kt_commit_plan` / `kt_push_plan`,按仓库分组确认范围。 diff --git a/src/registerTools.ts b/src/registerTools.ts index 62fdabb..c76c52b 100644 --- a/src/registerTools.ts +++ b/src/registerTools.ts @@ -374,7 +374,7 @@ export function registerTools(server: McpServer): void { 'kt_napcat_device_profile_check', { description: - '静态检查 API NapCat 设备身份护栏:QQNT 可见 hostname、02:42 MAC、machine-info、runtime dir 和 DB_TIMEZONE。', + '静态检查 API NapCat 设备身份护栏:QQNT 可见 hostname、实体 OUI MAC、machine-info、runtime dir 和 DB_TIMEZONE。', inputSchema: { project: z.string().default('api'), }, diff --git a/src/selfTest.ts b/src/selfTest.ts index 6c215e2..5178b2d 100644 --- a/src/selfTest.ts +++ b/src/selfTest.ts @@ -1026,6 +1026,18 @@ export async function runSelfTest(): Promise { throw new Error("database migration verification self-check failed"); } + const qqbotAccountScanPlan = buildBusinessTestPlan({ + flow: "qqbot-account-scan", + }); + const qqbotAccountScanText = JSON.stringify(qqbotAccountScanPlan); + if ( + !qqbotAccountScanText.includes("pending sessionId") || + !qqbotAccountScanText.includes("第一轮 Docker run") || + !qqbotAccountScanText.includes("不能造脏数据") + ) { + throw new Error("QQBot account scan non-dirty smoke self-check failed"); + } + const closeoutNeedsUpgrade = buildWorkstreamCloseout({ cleanupEvidence: ["cleanup-history dry-run deleted=0。"], docSyncEvidence: ["kt_change_doc_sync requiredDocs 已处理。"], diff --git a/src/tools/testing.ts b/src/tools/testing.ts index 14c5cd1..d56ba85 100644 --- a/src/tools/testing.ts +++ b/src/tools/testing.ts @@ -44,7 +44,7 @@ function createNapcatCheck( /** * Checks that the API project still contains the NapCat device-profile guardrails needed to avoid unknown QQ devices. * @param input - Project alias or path to scan; defaults to the API backend. - * @returns Static guardrail report covering hostname, MAC, machine-info, runtime dir, and DB timezone. + * @returns Static guardrail report covering hostname, physical-style MAC, machine-info, runtime dir, and DB timezone. */ export function buildNapcatDeviceProfileCheck( input: NapcatDeviceProfileCheckInput = {}, @@ -76,10 +76,12 @@ export function buildNapcatDeviceProfileCheck( 'device identity uses qqnt-visible-hostname-v1 and pc-<8hex>', ), createNapcatCheck( - 'docker-bridge-mac-strategy', - deviceIdentity.includes('docker-bridge-mac-v1') && - deviceIdentity.includes('02:42:'), - 'device identity uses docker-bridge-mac-v1 and stable 02:42:* MACs', + 'physical-oui-mac-strategy', + deviceIdentity.includes('physical-oui-mac-v1') && + deviceIdentity.includes('hasPhysicalOuiMacPrefix') && + deviceIdentity.includes('isRejectedVirtualMacPrefix') && + deviceIdentity.includes('NAPCAT_PHYSICAL_OUI_PREFIXES'), + 'device identity uses physical-oui-mac-v1 and rejects Docker/QEMU virtual MAC prefixes', ), createNapcatCheck( 'machine-info-options', @@ -230,13 +232,26 @@ export function buildBusinessTestPlan(input: BusinessTestPlanInput = {}): Record }, 'qqbot-account-scan': { assertions: [ - '扫码创建返回 qrcode/containerName/webuiPort。', + '扫码创建接口先返回 pending sessionId,再通过 SSE/status 展示容器创建、二维码生成、等待扫码和终态。', + '新增账号首次容器创建必须在第一轮 Docker run 注入设备身份和中文桌面 runtime profile,而不是登录后补 env。', '取消/过期/失败会清理未绑定 NapCat 容器。', + '若真实接口 smoke 会创建线上 QQBot 账号或 NapCat 容器,必须先确认清理方案;不能造脏数据时用 RED/GREEN、只读线上计数复核和未执行真实造号原因替代。', '删除账号会二次确认并删除专属容器。', ], - preflight: ['NAS SSH 可达', 'NapCat WebUI 可达', 'API QQBot env 配置完整'], + preflight: [ + 'NAS SSH 可达', + 'NapCat WebUI 可达', + 'API QQBot env 配置完整', + '确认本轮是否允许创建真实 QQBot 账号和 NapCat 容器', + ], projects: ['api', 'admin'], - steps: ['打开账号连接页', '点击扫码新增账号', '轮询二维码状态', '确认账号回填', '测试删除联动容器'], + steps: [ + '打开账号连接页', + '点击扫码新增账号并确认接口不等待 Docker/WebUI 长耗时', + '订阅 scan/events 或轮询 status 确认中文进度', + '确认账号回填和 runtime/profile 归属', + '测试删除联动容器或记录未造号的替代验证证据', + ], }, 'qqbot-login-sse': { assertions: [