| Files | Last commit | Last update |
|---|---|---|
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago | |
fix: 错误码映射 + 常量时间比较 + 前端端口可配置 可用性实测(新装环境跑完整旅程 21/21)暴露的三个问题: 1. 413 被降级成 400:media 上传超限抛 HTTPException(413),但异常处理器 只映射 404/405/5xx,其余一律 BAD_REQUEST。客户端看到"请求参数错误", 完全看不出是体积超限。补 413/409/422/429/502/503 的逐码映射。 2. token 比较用 !=(非常量时间):按首个不同字节短路,可做时序侧信道 逐字节还原 token。改 hmac.compare_digest。 3. Vite 代理写死 127.0.0.1:8000:8000 被占是常态,用户改端口就得改源码。 改为 HARBOR_API_PORT / HARBOR_API_URL 可配,实测指向 8401 后前端正常。 验证: - 新装端到端 21/21(空库→写作→编辑→版本→质检→导出→标签→15 平台→探针→删除) - 新装配置不再带开发 token(迁移时剔除凭据) - 浏览器:新装首屏/保存/导出菜单/设置页 7/7,零控制台错误 - 门禁:后端 597 passed、前端 77 passed、八道 exit=0 | 18 hours ago | |
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago | |
chore: 清空全部存量技术债——lint 68 条归零 + docs 目录迁移(0.6.4) 台账列的债先核实真实性再动手,其中一项的描述已过期。 一、台账纠正 #3(update/sync 切流引擎)标记为"早已完成",不是待办。核实证据: - service.py:876 update_single 已抽出,注释写明"R3 门禁:行为逐字不变" - tasks.py:183 _dispatch 已处理 update / sync - api/hub.py:263-276 三套入口(legacy/async/workflow)已合一,无回退分支 台账写于 2026-09-22 基线,0.4.0 大清理时就完成了,台账没跟上。按过期台账动主路径 才是真风险,故不执行 T3。 #5 维持不还:其自定触发条件(首次真实崩溃 / 上无人值守环境)均未发生。 二、lint 68 条归零,且门禁从 3 条规则扩到全量 0.6.3 定过"全开只会产出 58 条噪音,没人看输出等于没门禁"。本轮证明这个判断 只对了一半:噪音是一次性存量,清完之后门禁是绿的(0 告警),且持续增量为零。 分四层处理,不一刀切自动 fix: - 38 条 F401/F541/E401 走 ruff --fix,之后逐文件读 diff 复核 - F841 死变量 6 处、F811 重定义 5 处:人工确认无行为风险后手改 - E702 分号多语句 10 处:手工拆行(ruff 不自动改),浏览器操作顺序逐字不变 - E402 的 9 处:逐一读上下文确认是"有意为之的后置 import"(config/__init__.py 先定义 __all__ 再 re-export;service.py 的导入必须排在常量之后,:37 的 "导入即注册"尤其不能动)→ 加 ignore 并把理由写进配置注释,不上移代码 **过程中抓到并修掉一个真 bug**:ruff --fix 删掉了 service.py 中 wait_human_captcha 的唯一引入点。该符号只在 solve_captcha 的浏览器分支用到, 159 个测试全绿也照样上线炸——纯靠测试抓不到这类"只在某条路径上可达"的符号。 由 F821 当场抓住,并新增 test_no_undefined_names_anywhere 把 F821 零命中 纳入回归。 三、docs 目录迁移(#11) ARCHITECTURE.md → docs/architecture/,AUDIT.md → docs/audit/(git 记录为 rename,历史保留)。 0.6.3 曾以"移动会让 CHANGELOG.md:159,177 的历史条目指向失效路径"为由跳过—— 该理由经核实不成立:全仓库只有 1 处 markdown 链接指向这两个文件(README.md), CHANGELOG 与 tech-debt 里的提及都是纯文本叙述而非链接。上一轮的判断是错的。 新增 test_docs_links.py(16 用例)守护三件事:相对链接可达、迁移落点固定、 AGENT.md 适配器清单与代码一致。最后一条当场抓到另一个问题:AGENT.md 的适配器 表写着"11 个",却列出 douyin/weibo/sf 等 5 个不存在的文件,同时漏掉 6 个真实 存在的(oschina/toutiao/zhihu/wuyi_cto/metaweblog/segmentfault)。已按 ADAPTERS 实际内容重写。 四、版本与文档 0.6.3 → 0.6.4(无运行时行为变更,uv.lock 依赖集合不变)。README/AGENT.md 测试用例数同步为 176。台账新增「已失效」一节,并记下 #11 先前后续的理由订正。 审计状态:与前三笔一致——hosted Decision Engine MCP 工具本环境不存在, DE Lite 本地桥为 macOS/Codex 专用,三方审核 gate 仍未关闭。本地四道门禁全绿。 | 28 days ago | |
feat: 0.9.0 遗留问题清零——外部 MCP 桥接/平台限流冷却/上传安全/AST 变换/架构拆分 外部 MCP Server 桥接(mcp_bridge.py): - Harbour 作为 MCP Client,官方 mcp SDK 2.3.0 stdio 拉起第三方 server - 工具白名单/超时兜底/默认关闭;REST 端点 3 个,MCP tool 27→30 - 端到端测试真实拉起子进程验证;已核实 @playwright/mcp 0.0.83、 mcp-server-fetch 2026.10.28、@wechatsync/cli 1.1.0 可直用 平台级限流冷却(ratelimit.py): - 解析 Retry-After(秒/HTTP-date)与 X-RateLimit-Reset(秒/毫秒) - 冷却按平台落 SQLite(只延长不缩短、到期自清、上限 30 分钟) - 适配器把限流头带进错误串;任务引擎识别 429/503 整体延后同平台任务 - /status 暴露冷却状态,POST /platform-cooldowns/clear 手动解除 媒体安全与对外地址: - 上传按内容校验(Pillow 魔数嗅探+格式白名单+4000 万像素上限), 伪装扩展名/解码炸弹被拒;SVG 刻意排除(XML 可携带脚本) - middleware/public_base.py 从请求 Host/XFF 自动探测对外地址, 不再强制手工配 PUBLIC_BASE_URL;/media/stats 显示来源与排查提示 AST 级内容变换(content_transform.py,markdown-it-py): - 去开头重复 H1/删正文标签行/图片 URL 改写,代码块天然不受影响 - 规则表按平台接线进 publish_single,失败退回原文 架构:service.py 988→483 行 - AST 机械切片成 article_ops/ai_ops/publish_ops 三个 mixin,行为逐字不变 - Hub 多继承组合,MRO 验证 + 全量测试锁行为 适配器离线契约探针(adapter_probe.py): - 接口实现/能力一致性/选择器合法性静态检查 - tests/fixtures/dom/*.html 采样后可做选择器漂移比对(平台改版信号) - GET /adapters/probe、POST /adapters/probe/{p}/dump 测试:后端 453→480;六道门禁全绿 | 8 days ago | |
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago | |
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago | |
fix: 错误码映射 + 常量时间比较 + 前端端口可配置 可用性实测(新装环境跑完整旅程 21/21)暴露的三个问题: 1. 413 被降级成 400:media 上传超限抛 HTTPException(413),但异常处理器 只映射 404/405/5xx,其余一律 BAD_REQUEST。客户端看到"请求参数错误", 完全看不出是体积超限。补 413/409/422/429/502/503 的逐码映射。 2. token 比较用 !=(非常量时间):按首个不同字节短路,可做时序侧信道 逐字节还原 token。改 hmac.compare_digest。 3. Vite 代理写死 127.0.0.1:8000:8000 被占是常态,用户改端口就得改源码。 改为 HARBOR_API_PORT / HARBOR_API_URL 可配,实测指向 8401 后前端正常。 验证: - 新装端到端 21/21(空库→写作→编辑→版本→质检→导出→标签→15 平台→探针→删除) - 新装配置不再带开发 token(迁移时剔除凭据) - 浏览器:新装首屏/保存/导出菜单/设置页 7/7,零控制台错误 - 门禁:后端 597 passed、前端 77 passed、八道 exit=0 | 18 hours ago | |
feat: 桌面端启动链路加固+生产级重构 (0.7.0) - TaskManager close() 补 join 守护线程,防进程退出时浏览器孤儿 - venv 路径多策略探测:VIRTUAL_ENV → .venv → 系统 python fallback - 新增 crypto.py: Fernet 加密落库(Webhook secret 等字段) - 重构 events.py: SSE 实时推送 + 加密签名 + 站内通知 - hub.js god store 拆分为 6 个领域 store (article/task/account/tag/schedule/webhook) - 提取 usePublishWizard composable(605行→110行模板) - api.js: 指数退避重试 + 后端不可达明确提示 - Tauri lib.rs: _find_venv_python() 多策略探测 - 修复 flaky test: _wait_task 容忍短暂 404 - 移除误提交的 Rust 构建产物 (target/, binaries/) 并加入 .gitignore | 28 days ago | |
refactor(brand): 品牌拼写全面统一 Harbor - 源码/文档/环境变量前缀 HARBOUR_→HARBOR_/请求头/桌面标识同步更新,后端 537 前端 66 测试通过 | 4 days ago | |
cleanup 0.4.0: unify codebase, demolish scaffold, fix security/docs Key changes: - Remove scaffold: api/v1, models, schemas, repository, services layers - Delete ghost infra: core/cache, core/queue, app/events, app/router - Rewrite ARCHITECTURE.md to actual 0.4.0 state - Fix hub.py (no global side effect, auto-token) - Fix humanize.py (WPM type formula was 5x off) - Fix observability.py (remove dead _observe_with_max, M_* constants) - Fix config_unified.py (Production reads env vars) - Fix factory.py (simplified lifespan, no cache/queue/DB pool) - Fix core/__init__.py (remove dead imports) - Fix api/__init__.py (hub_router not v1) - Fix app/exceptions.py (inline schemas) - Fix frontend Vue components (App.vue, ArticleList, ArticleEditor) - Rename deplay/ -> deploy/ - Version: 0.4.0-fix | 29 days ago | |
cleanup 0.4.0: unify codebase, demolish scaffold, fix security/docs Key changes: - Remove scaffold: api/v1, models, schemas, repository, services layers - Delete ghost infra: core/cache, core/queue, app/events, app/router - Rewrite ARCHITECTURE.md to actual 0.4.0 state - Fix hub.py (no global side effect, auto-token) - Fix humanize.py (WPM type formula was 5x off) - Fix observability.py (remove dead _observe_with_max, M_* constants) - Fix config_unified.py (Production reads env vars) - Fix factory.py (simplified lifespan, no cache/queue/DB pool) - Fix core/__init__.py (remove dead imports) - Fix api/__init__.py (hub_router not v1) - Fix app/exceptions.py (inline schemas) - Fix frontend Vue components (App.vue, ArticleList, ArticleEditor) - Rename deplay/ -> deploy/ - Version: 0.4.0-fix | 29 days ago | |
fix(security): 五类真实漏洞 + 配置污染(黑盒攻击测试驱动) 用 43 项黑盒攻击(真实 HTTP,不是读代码猜)打出来的问题: 1. webhook 完全无目标校验 —— 可注册到 169.254.169.254 与 127.0.0.1, 成为标准 SSRF 原语。补注册/更新/投递三道校验,注册时对"域名还没上线" 放行(自建站常见),投递时再严格解析,防 DNS rebinding。 自托管推内网 n8n 属正当需求,给 allow_private 显式开关。 2. 500 响应泄漏完整 traceback(本地绝对路径 + 源码行 + 调用栈)。 根因是 FastAPI(debug=settings.debug) 让 Starlette 的 ServerErrorMiddleware 绕过统一 JSON 处理器。改为 debug 恒关,响应体只给固定文案,细节进日志。 3. Server 响应头删不掉 —— 中间件里 del 无效,uvicorn 在中间件之后才写协议层。 三个启动入口(start.py / desktop_sidecar.py / cli serve)统一 server_header=False。 4. AI provider base_url 可指向任意地址 —— 决定 API Key 发往哪个主机, 允许任意值等于允许静默改道密钥 + SSRF。补校验(放行回环以支持 Ollama)。 5. 首次启动迁移旧配置时整份复制,把开发机 api_token 带进新数据目录 —— 所有安装共用同一 token,等于没有鉴权。改为迁移后剔除凭据字段, 且不含凭据时保持逐字节不变(既有契约)。 6. 测试污染真实配置:ai_config 的 CONFIG_FILE 在 import 时钉死路径, 新增用例把 providers 段落写进了 backed/config.json。 改为惰性解析 + 全局限定 HARBOR_CONFIG_FILE;已验证跑完全量后 md5 不变。 顺带修掉 auth._resolve_token 的恒假死分支(ROOT != Path(__file__).parent.parent)。 验证: - 黑盒攻击 43/43 防御生效(SSRF 16 项、路径穿越 9 项、上传 3 项、注入 2 项…) - 新增 26 条安全回归测试(含"注册合法再 PUT 成内网"的绕过路径) - 门禁:后端 595 passed、前端 77 passed、ruff 0 错、八道 exit=0 - 配置污染反证:跑全量前后 backed/config.json md5 一致 | 18 hours ago | |
fix(security): 收紧网络边界、生命周期与凭据暴露面 浏览器操控面(/browser/fetch、/browser/screenshot)此前因 DNS 重绑定 风险被整体禁用。改用 Chromium --host-resolver-rules 把目标主机钉在 已校验的公网 IP 上,并加请求级守卫拦截解析到内网的子资源与跨域跳转, 功能恢复且不依赖"信任浏览器自己解析"。 - 新增 url_safety:公网 IP 校验、超时钳制、连接钉扎抓取(fetch_pinned)、 逐跳重定向校验、并发与体积上限 - 网页导入与浏览器操控共用同一套校验;Markdown 导入限制在安全根内、 只允许 .md/.markdown、拒绝配置与数据库文件、加体积上限 - MCP SSE 默认只绑定回环,远程必须配置 HARBOUR_MCP_TOKEN;外部 MCP 子进程改用白名单环境,不再继承父进程密钥 - 关闭流程按 scheduler → tasks → browser → dispatcher → DB 顺序幂等执行, 停止失败时保留连接而不是伪装成功 - 运行配置与数据库/媒体/登录态统一到同一数据根,旧 backed/config.json 只作只读迁移来源 - 前端令牌存本机浏览器,SSE 改 fetch 流以携带 X-API-Token - 文档与代码对齐:删除单文件 exe、8 Provider、30 Tool 等不实表述 - 整理仓库:审计报告与技术文章归入 docs/,清理临时产物与缓存 后端 529 passed,前端 63 passed,ruff 全绿。 | 5 days ago | |
fix(security): 五类真实漏洞 + 配置污染(黑盒攻击测试驱动) 用 43 项黑盒攻击(真实 HTTP,不是读代码猜)打出来的问题: 1. webhook 完全无目标校验 —— 可注册到 169.254.169.254 与 127.0.0.1, 成为标准 SSRF 原语。补注册/更新/投递三道校验,注册时对"域名还没上线" 放行(自建站常见),投递时再严格解析,防 DNS rebinding。 自托管推内网 n8n 属正当需求,给 allow_private 显式开关。 2. 500 响应泄漏完整 traceback(本地绝对路径 + 源码行 + 调用栈)。 根因是 FastAPI(debug=settings.debug) 让 Starlette 的 ServerErrorMiddleware 绕过统一 JSON 处理器。改为 debug 恒关,响应体只给固定文案,细节进日志。 3. Server 响应头删不掉 —— 中间件里 del 无效,uvicorn 在中间件之后才写协议层。 三个启动入口(start.py / desktop_sidecar.py / cli serve)统一 server_header=False。 4. AI provider base_url 可指向任意地址 —— 决定 API Key 发往哪个主机, 允许任意值等于允许静默改道密钥 + SSRF。补校验(放行回环以支持 Ollama)。 5. 首次启动迁移旧配置时整份复制,把开发机 api_token 带进新数据目录 —— 所有安装共用同一 token,等于没有鉴权。改为迁移后剔除凭据字段, 且不含凭据时保持逐字节不变(既有契约)。 6. 测试污染真实配置:ai_config 的 CONFIG_FILE 在 import 时钉死路径, 新增用例把 providers 段落写进了 backed/config.json。 改为惰性解析 + 全局限定 HARBOR_CONFIG_FILE;已验证跑完全量后 md5 不变。 顺带修掉 auth._resolve_token 的恒假死分支(ROOT != Path(__file__).parent.parent)。 验证: - 黑盒攻击 43/43 防御生效(SSRF 16 项、路径穿越 9 项、上传 3 项、注入 2 项…) - 新增 26 条安全回归测试(含"注册合法再 PUT 成内网"的绕过路径) - 门禁:后端 595 passed、前端 77 passed、ruff 0 错、八道 exit=0 - 配置污染反证:跑全量前后 backed/config.json md5 一致 | 18 hours ago | |
fix: 六项真实缺陷 + 三项能力补齐(全链路实跑驱动) 全链路实跑(91 个 REST 端点 / 32 个 MCP 工具 / 34 个 CLI 命令 / 浏览器逐页) 暴露的问题,逐条连根修并补反证测试: 缺陷 1. /api/info 返回 91 条空记录:FastAPI 0.141 起 include_router 插入 _IncludedRouter 包装,getattr(route,"path") 取空。改为递归展开子路由。 2. AI 就绪状态造假:Ollama 无需密钥,is_ready() 恒为 True。本机 11434 无 监听时界面仍显示绿色「AI 就绪」+ 卡片「可用」,点一下就连接被拒。 改为对本地无密钥 provider 做短超时探活,卡片区分「服务未启动」。 3. Markdown 编辑器主题写死 dark:亮色用户在编辑器里得到一块黑底。 改为订阅全局主题,切换与冷启动都跟随。 4. Prometheus 直方图导出全 0.0:直写 _buckets 私有字段无效。改用公开 observe() 按桶差值补点,桶计数与 sum/count 与 JSON 一致。 5. 安全响应头默认全关:默认部署 /health 一个安全头都没有。安全头默认开 (纯响应头、不改请求语义),CSP 经浏览器实测零违规。 6. 打包版上传图片必崩:pyinstaller.spec 排除 PIL,而 media.py 运行时用 PIL 做图片魔数校验。同时清掉 spec 里不存在的 md_editor_v3/playwright。 能力补齐 - 标签推荐离线兜底:无 AI 时原来返回空串("点了没反应")。新增关键词命中 + 同义词去重(golang/go、kubernetes/k8s 不再同时推荐)。 - Markdown 导出:GET /articles/{id}/export + CLI export + 编辑器菜单, 带 YAML front-matter,Hexo/Hugo/Obsidian 可直接用(此前内容只进不出)。 - GFM 补齐:~~删除线~~ 以前原样漏到平台,现转 <del>,代码块与行内代码受保护。 - CLI 补 list/show/edit/delete/search/export,此前只能建不能改不能查。 门禁:后端 537→558 passed(连跑稳定);前端 66→71 passed;ruff 0 错; 八道全绿。exe 实测:创建文章 / 标签推荐 / 图片校验 / 91 条路由表均正常。 | 21 hours ago | |
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago | |
fix(security): 五类真实漏洞 + 配置污染(黑盒攻击测试驱动) 用 43 项黑盒攻击(真实 HTTP,不是读代码猜)打出来的问题: 1. webhook 完全无目标校验 —— 可注册到 169.254.169.254 与 127.0.0.1, 成为标准 SSRF 原语。补注册/更新/投递三道校验,注册时对"域名还没上线" 放行(自建站常见),投递时再严格解析,防 DNS rebinding。 自托管推内网 n8n 属正当需求,给 allow_private 显式开关。 2. 500 响应泄漏完整 traceback(本地绝对路径 + 源码行 + 调用栈)。 根因是 FastAPI(debug=settings.debug) 让 Starlette 的 ServerErrorMiddleware 绕过统一 JSON 处理器。改为 debug 恒关,响应体只给固定文案,细节进日志。 3. Server 响应头删不掉 —— 中间件里 del 无效,uvicorn 在中间件之后才写协议层。 三个启动入口(start.py / desktop_sidecar.py / cli serve)统一 server_header=False。 4. AI provider base_url 可指向任意地址 —— 决定 API Key 发往哪个主机, 允许任意值等于允许静默改道密钥 + SSRF。补校验(放行回环以支持 Ollama)。 5. 首次启动迁移旧配置时整份复制,把开发机 api_token 带进新数据目录 —— 所有安装共用同一 token,等于没有鉴权。改为迁移后剔除凭据字段, 且不含凭据时保持逐字节不变(既有契约)。 6. 测试污染真实配置:ai_config 的 CONFIG_FILE 在 import 时钉死路径, 新增用例把 providers 段落写进了 backed/config.json。 改为惰性解析 + 全局限定 HARBOR_CONFIG_FILE;已验证跑完全量后 md5 不变。 顺带修掉 auth._resolve_token 的恒假死分支(ROOT != Path(__file__).parent.parent)。 验证: - 黑盒攻击 43/43 防御生效(SSRF 16 项、路径穿越 9 项、上传 3 项、注入 2 项…) - 新增 26 条安全回归测试(含"注册合法再 PUT 成内网"的绕过路径) - 门禁:后端 595 passed、前端 77 passed、ruff 0 错、八道 exit=0 - 配置污染反证:跑全量前后 backed/config.json md5 一致 | 18 hours ago | |
release: 0.15.0 - 发布后回读(让"成功"等于平台上真有这篇) 核心:接口返回 200 不等于发布成功。0.8→0.14 所有"假成功"缺陷都出在这个缝里 (掘金只发草稿、知乎编辑器没替换、思否按钮 disabled 也走成功分支)。本版加一层 统一的结果级证据:发布完再去平台读一次,读得到的才算数。 功能 - publications 新增 verify_state/verified_at/verify_detail 四态: verified / failed / unsupported / unverified。默认 unverified 而非 verified。 - 协议平台回读:Dev.to(article API 比对标题与 body_markdown)、 GitHub Pages(contents API 解码比对 + 站点层探活)。 - 页面平台回读:通用 read_back_in_page(),与编辑器回读共用 content_evidence / title_evidence。 - POST /api/v1/hub/publications/{id}/verify 随时重核。 - 发布中心新增「回读」列 + 「重新回读」按钮。 - scripts/verify_real_publish.py:可复跑的真机发布验证(真 commit、真回读、 真站点探活、原地更新再验证、默认自动清理)。 - docs/verification/index.md 验证记录索引。 真机验证发现的 4 个缺陷(所有 mock 与仓库级检查都无感) - GitHub Pages 发布出来是 404:front-matter date 用本地时间(UTC+8), Pages 构建机在 UTC,文章被当成"未来日期",Jekyll 默认 future:false 静默丢弃。 commit 成功、API 回读成功、list_articles 看得到,公开链接 404。 改为统一 UTC 并显式 +0000。 - 回读 URL 用"现在"重算:跨过 UTC 零点回读必然指向不存在的日期目录。 改为优先用发布时记录的 post_url。 - 标题比对被站点后缀打挂:<title> 是"文章标题_CSDN博客",改为剥掉分隔符 后缀再比(必须在 _flatten 之前剥)。 - 已发布页面被追加检测误杀:content_evidence 的"首段必须在正文开头"是为编辑器 设计的,套到已发布页面必然误判(页面正文前有 470 字导航栏)。 新增 check_lead 开关:页面类回读关闭,编辑器回读保持开启。 - Pages 构建异步被误判为失败:改为查 /pages/builds/latest,区分 building (标"稍后复核")与 errored(真失败)。 CI / 打包 - CI 在三个 GitHub 镜像仓连红两天。根因:web/pnpm-workspace.yaml 只有 allowBuilds 没有 packages,pnpm 9+ 进入 workspace 模式后直接报 "packages field missing or empty",install 失败,后面 lint/test/build 全 skipped。 本地因 node_modules 已存在从未暴露。补 packages: ["."],并锁 packageManager: pnpm@9.15.9 防止漂移。 - MSI 打不出来:productName 是中文,WiX 3.14 默认代码页 1252 装不下 CJK, light.exe 直接退出。加 bundle.windows.wix.language=["zh-CN"] 后通过 (54.93 MiB)。 - CI 新增 docker-smoke(compose config → build → up → 容器内 healthcheck → 认证 API 调用 → teardown)与 desktop-build(windows-latest 打 NSIS+MSI)。 原注释"未验证所以不上 Docker/Tauri"的取舍到此作废。 - 本机实测:NSIS 53.3MB + MSI 54.93MB,msiexec /qn 静默安装 exit 0, harbor.exe 自动拉起 sidecar,/api/v1/hub/health 返回 ok, 数据目录 %APPDATA%\com.harbor.hub,msiexec /x /qn 卸载干净。 其他 - README 07-tags.png 从未被脚本生成过(截图脚本漏了标签治理面板),补上。 - 修正验证记录测试数:651 → 675(+14 回读层、+10 标题证据规则)。 门禁:后端 675 passed、前端 77 passed、lint 0 errors、ruff 通过、 密钥扫描 0 findings、版本 5/5 一致、八道 exit=0。 已知限制(如实记录):浏览器类平台仅 CSDN 真机回读;devto/telegraph 未对真实 账号发布;docker-smoke 与 desktop-build 的首次 CI 绿跑待本次提交后确认。 | 6 hours ago |
| Files | Last commit | Last update |
|---|---|---|
| 6 hours ago | ||
| 18 hours ago | ||
| 6 hours ago | ||
| 28 days ago | ||
| 8 days ago | ||
| 6 hours ago | ||
| 6 hours ago | ||
| 18 hours ago | ||
| 28 days ago | ||
| 4 days ago | ||
| 29 days ago | ||
| 29 days ago | ||
| 18 hours ago | ||
| 5 days ago | ||
| 18 hours ago | ||
| 21 hours ago | ||
| 6 hours ago | ||
| 18 hours ago | ||
| 6 hours ago |