red-blue-cp 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- red_blue_cp-0.3.0/.env.example +40 -0
- red_blue_cp-0.3.0/.github/workflows/ci.yml +23 -0
- red_blue_cp-0.3.0/.github/workflows/publish.yml +55 -0
- red_blue_cp-0.3.0/.gitignore +14 -0
- red_blue_cp-0.3.0/.leak-patterns.example +26 -0
- red_blue_cp-0.3.0/CLAUDE.md +237 -0
- red_blue_cp-0.3.0/LICENSE +21 -0
- red_blue_cp-0.3.0/LOG.md +139 -0
- red_blue_cp-0.3.0/PKG-INFO +153 -0
- red_blue_cp-0.3.0/PLAN.md +389 -0
- red_blue_cp-0.3.0/PRD.md +185 -0
- red_blue_cp-0.3.0/README.md +122 -0
- red_blue_cp-0.3.0/REFERENCES.md +131 -0
- red_blue_cp-0.3.0/SPEC.md +522 -0
- red_blue_cp-0.3.0/app/__init__.py +0 -0
- red_blue_cp-0.3.0/app/cli.py +326 -0
- red_blue_cp-0.3.0/app/service/__init__.py +0 -0
- red_blue_cp-0.3.0/app/service/comments.py +154 -0
- red_blue_cp-0.3.0/app/service/discover.py +723 -0
- red_blue_cp-0.3.0/app/service/extractor.py +275 -0
- red_blue_cp-0.3.0/app/service/fetcher.py +396 -0
- red_blue_cp-0.3.0/app/service/markdown.py +148 -0
- red_blue_cp-0.3.0/app/service/model.py +416 -0
- red_blue_cp-0.3.0/app/service/storage.py +193 -0
- red_blue_cp-0.3.0/app/service/templates/note.md.j2 +41 -0
- red_blue_cp-0.3.0/app/web/__init__.py +0 -0
- red_blue_cp-0.3.0/app/web/routes.py +233 -0
- red_blue_cp-0.3.0/app/web/templates/base.html +464 -0
- red_blue_cp-0.3.0/app/web/templates/detail.html +190 -0
- red_blue_cp-0.3.0/app/web/templates/index.html +285 -0
- red_blue_cp-0.3.0/docs/assets/banner.png +0 -0
- red_blue_cp-0.3.0/docs/deploy-wsl.md +193 -0
- red_blue_cp-0.3.0/docs/devlog/2026-05-09-integration-layer-bugs.md +100 -0
- red_blue_cp-0.3.0/docs/devlog/2026-05-09-m0-upstream-analysis.md +335 -0
- red_blue_cp-0.3.0/docs/devlog/2026-05-09-naming-red-blue-cp.md +123 -0
- red_blue_cp-0.3.0/docs/devlog/2026-05-09-p0-delivery.md +101 -0
- red_blue_cp-0.3.0/docs/devlog/2026-05-09-p0-keep-it-simple.md +113 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-02-blogger-full-and-comments-design.md +152 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-02-parallel-subagent-tdd-lessons.md +58 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-02-xhs-blogger-full-fetch-via-interceptor.md +100 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-03-product-form-and-v3-scope.md +89 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-03-pydoll-native-capture-and-login.md +63 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-03-retro-p1-claude-code.md +91 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-03-webui-redesign-and-qa.md +74 -0
- red_blue_cp-0.3.0/docs/devlog/2026-06-03-when-to-parallelize-and-research-layering.md +58 -0
- red_blue_cp-0.3.0/docs/devlog/TEMPLATE.md +56 -0
- red_blue_cp-0.3.0/docs/gstack/ceo-plans/2026-05-09-p0-from-scratch.md +172 -0
- red_blue_cp-0.3.0/docs/gstack/designs/2026-05-09-p0-design.md +138 -0
- red_blue_cp-0.3.0/docs/project-overview.html +2904 -0
- red_blue_cp-0.3.0/docs/reference/xhs-api-notes.md +149 -0
- red_blue_cp-0.3.0/docs/release-pypi.md +87 -0
- red_blue_cp-0.3.0/pyproject.toml +54 -0
- red_blue_cp-0.3.0/scripts/check-leaks.sh +68 -0
- red_blue_cp-0.3.0/tests/__init__.py +0 -0
- red_blue_cp-0.3.0/tests/fixtures/xhs/README.md +32 -0
- red_blue_cp-0.3.0/tests/fixtures/xhs/comment_page.json +90 -0
- red_blue_cp-0.3.0/tests/fixtures/xhs/comment_sub_page.json +74 -0
- red_blue_cp-0.3.0/tests/fixtures/xhs/user_posted_last.json +38 -0
- red_blue_cp-0.3.0/tests/fixtures/xhs/user_posted_page1.json +92 -0
- red_blue_cp-0.3.0/tests/test_cli.py +56 -0
- red_blue_cp-0.3.0/tests/test_comments.py +246 -0
- red_blue_cp-0.3.0/tests/test_discover_parse.py +346 -0
- red_blue_cp-0.3.0/tests/test_extractor.py +296 -0
- red_blue_cp-0.3.0/tests/test_extractor_flags.py +544 -0
- red_blue_cp-0.3.0/tests/test_markdown_render.py +133 -0
- red_blue_cp-0.3.0/tests/test_model.py +415 -0
- red_blue_cp-0.3.0/tests/test_p2_wiring.py +336 -0
- red_blue_cp-0.3.0/tests/test_pipeline.py +80 -0
- red_blue_cp-0.3.0/tests/test_routes.py +355 -0
- red_blue_cp-0.3.0/tests/test_sanitize.py +148 -0
- red_blue_cp-0.3.0/tests/test_storage.py +259 -0
- red_blue_cp-0.3.0/tests/test_web_templates.py +177 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Red Blue CP 配置
|
|
2
|
+
# 复制此文件为 .env 并填入实际值
|
|
3
|
+
|
|
4
|
+
# ── 必填 ──────────────────────────────────────────────────────
|
|
5
|
+
DASHSCOPE_API_KEY=sk-your-dashscope-api-key-here
|
|
6
|
+
|
|
7
|
+
# ── 可选 ──────────────────────────────────────────────────────
|
|
8
|
+
# 小红书 cookie。单篇公开笔记的"正文转录"不需要;
|
|
9
|
+
# 「带评论」「博主全量/批量」需要(这两个走浏览器代签,要登录态)。
|
|
10
|
+
# 来源二选一:
|
|
11
|
+
# 1) XHS_COOKIE:原始 cookie 串(从浏览器开发者工具复制),生产首选
|
|
12
|
+
# XHS_COOKIE=web_session=...; a1=...
|
|
13
|
+
# 2) RBCP_XHS_COOKIE_FILE:指向 cookie JSON 文件(Playwright/CDP 导出格式,
|
|
14
|
+
# {"cookies":[...]} 或裸数组皆可)。dev/自动化用;XHS_COOKIE 存在时优先用它。
|
|
15
|
+
# RBCP_XHS_COOKIE_FILE=
|
|
16
|
+
|
|
17
|
+
# Markdown 输出目录(默认 ~/transcript)
|
|
18
|
+
# RBCP_OUTPUT_DIR=~/transcript
|
|
19
|
+
|
|
20
|
+
# 原始媒体落盘目录(仅 --save-media 时用;独立于知识库,默认 ~/transcript-media)
|
|
21
|
+
# RBCP_MEDIA_DIR=~/transcript-media
|
|
22
|
+
|
|
23
|
+
# 博主全量抓取调参(一般不用动)
|
|
24
|
+
# RBCP_DISCOVER_SCROLL_WAIT=2.2 # 每次滚动后等待秒数
|
|
25
|
+
# RBCP_DISCOVER_MAX_PAGES=80 # 安全上限,防失控翻页
|
|
26
|
+
|
|
27
|
+
# ASR 模型(默认 paraformer-v2,可选 qwen3-asr-flash-filetrans)
|
|
28
|
+
# RBCP_ASR_MODEL=paraformer-v2
|
|
29
|
+
|
|
30
|
+
# 说话人分离(默认开;多人对谈正文标注「说话人N:」,单人自动降级纯文本)
|
|
31
|
+
# RBCP_ASR_DIARIZATION=true
|
|
32
|
+
|
|
33
|
+
# 说话人数量提示(整数 2-100,不填自动判断;填了也只是辅助算法尽量输出该人数)
|
|
34
|
+
# RBCP_ASR_SPEAKER_COUNT=
|
|
35
|
+
|
|
36
|
+
# VLM 模型(默认 qwen3-vl-flash)
|
|
37
|
+
# RBCP_VLM_MODEL=qwen3-vl-flash
|
|
38
|
+
|
|
39
|
+
# LLM 文本清洗模型(默认 qwen-plus)
|
|
40
|
+
# RBCP_LLM_MODEL=qwen-plus
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# 推到 main 或开 PR 时跑测试。243 个测试全部离线(外部 API 已 mock),不需要密钥。
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v5
|
|
20
|
+
with:
|
|
21
|
+
enable-cache: true
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: uv run --python ${{ matrix.python-version }} pytest -q
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# 打 tag(如 v0.3.0)时:跑测试 → build → 发布到 PyPI。
|
|
4
|
+
#
|
|
5
|
+
# 用 PyPI Trusted Publishing(OIDC),不在仓库存 token。一次性配置:
|
|
6
|
+
# 1. 去 https://pypi.org/manage/account/publishing/ 加一个 "pending publisher"
|
|
7
|
+
# (项目还没发布过时用 pending;已发布过则在项目设置里加):
|
|
8
|
+
# - PyPI Project Name: red-blue-cp
|
|
9
|
+
# - Owner: MuChengZJU
|
|
10
|
+
# - Repository name: red-blue-cp
|
|
11
|
+
# - Workflow name: publish.yml
|
|
12
|
+
# - Environment name: pypi
|
|
13
|
+
# 2. 在 GitHub 仓库 Settings → Environments 建一个名为 `pypi` 的 environment。
|
|
14
|
+
# 3. 之后 `git tag v0.3.0 && git push origin v0.3.0` 即自动发布。
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
tags: ["v*"]
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: astral-sh/setup-uv@v5
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
- run: uv run pytest -q
|
|
28
|
+
|
|
29
|
+
build:
|
|
30
|
+
needs: test
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: astral-sh/setup-uv@v5
|
|
35
|
+
- run: uv build
|
|
36
|
+
- uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
|
|
41
|
+
publish:
|
|
42
|
+
needs: build
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
environment:
|
|
45
|
+
name: pypi
|
|
46
|
+
url: https://pypi.org/p/red-blue-cp
|
|
47
|
+
permissions:
|
|
48
|
+
id-token: write # Trusted Publishing 需要,用来向 PyPI 换取一次性令牌
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
54
|
+
- name: Publish to PyPI
|
|
55
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 复制本文件为 .leak-patterns.local(已 gitignored),把"YOUR_*"替换成实际敏感词。
|
|
2
|
+
# 一行一个。空行和 # 开头的行会被忽略。
|
|
3
|
+
# scripts/check-leaks.sh 会按这里列的关键词扫描所有 tracked 文档。
|
|
4
|
+
|
|
5
|
+
# === 个人身份 ===
|
|
6
|
+
YOUR_REAL_NAME
|
|
7
|
+
YOUR_NICKNAME_OR_ALIAS
|
|
8
|
+
YOUR_EMAIL_HANDLE
|
|
9
|
+
YOUR_DEVICE_NAME
|
|
10
|
+
|
|
11
|
+
# === 学术 / 工作环境 ===
|
|
12
|
+
YOUR_SCHOOL_NAME
|
|
13
|
+
YOUR_LAB_NAME
|
|
14
|
+
YOUR_ADVISOR_NAME
|
|
15
|
+
YOUR_COWORKER_NAME
|
|
16
|
+
YOUR_EMPLOYER_NAME
|
|
17
|
+
YOUR_SIDE_PROJECT_NAME
|
|
18
|
+
|
|
19
|
+
# === 时间盘 / 进度 ===
|
|
20
|
+
# 任何能反推个人时间表的具体短语,比如重大日期、考试名、结业相关
|
|
21
|
+
# YOUR_MILESTONE_KEYWORD
|
|
22
|
+
|
|
23
|
+
# === 路径 ===
|
|
24
|
+
# 含家目录用户名的路径
|
|
25
|
+
/Users/YOUR_USERNAME
|
|
26
|
+
/home/YOUR_USERNAME
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# CLAUDE.md · Red Blue CP
|
|
2
|
+
|
|
3
|
+
> 这个文件是 Claude Code 在本仓库工作时的规则书。每次对话开始时自动读。
|
|
4
|
+
> 修改前先看 PRD.md / SPEC.md,理解上下文。
|
|
5
|
+
|
|
6
|
+
## 项目目标(一句话)
|
|
7
|
+
|
|
8
|
+
**Red Blue CP(红蓝CP)—— 自古红蓝出 CP,B 站小红书 Content Pipeline。**
|
|
9
|
+
|
|
10
|
+
把 B 站和小红书的视频/图文内容转成纯文本,沉淀成本地 Markdown 知识库。
|
|
11
|
+
|
|
12
|
+
## 当前阶段
|
|
13
|
+
|
|
14
|
+
**P0 已完成**(M0 + M1a + M1b + M1c 说话人分离),对应首个可用版本 **v0.1.0**,已 MIT 开源。
|
|
15
|
+
URL → Markdown 文件闭环目标已达成,145 个测试通过。
|
|
16
|
+
|
|
17
|
+
**P1/P2 未启动**。未经确认不要开 P1/P2 范围的功能(批量、博主全量、评论、模型抽象等),即便代码看起来该重构。
|
|
18
|
+
当前以维护和文档为主;要进 P1 需先在对话里确认。
|
|
19
|
+
|
|
20
|
+
## 不变量(红线,违反就是 bug)
|
|
21
|
+
|
|
22
|
+
### 安全
|
|
23
|
+
|
|
24
|
+
1. **文件下载/读取接口必须走 `job_id`**,不允许用户传任意 file path。任何 `GET /api/files/{path}` 这类设计都是路径穿越漏洞,禁止。
|
|
25
|
+
2. **敏感配置不进 Git**。百炼 API Key 和小红书 cookie 存放在 `.env` 文件中,必须在 `.gitignore` 里。
|
|
26
|
+
|
|
27
|
+
### 部署
|
|
28
|
+
|
|
29
|
+
3. **MVP 仅支持单进程 uvicorn**。启动命令禁止 `--workers > 1`。asyncio.Queue / create_task 是进程内的,多 worker 会让任务状态混乱。
|
|
30
|
+
4. **不允许把数据库或日志写到 `~/transcript/`**。知识库目录只放 Markdown 文件。SQLite 索引文件 `_index.sqlite` 是唯一例外。
|
|
31
|
+
|
|
32
|
+
### 持久化
|
|
33
|
+
|
|
34
|
+
5. **媒体文件不进知识库**。知识库目录(`~/transcript`)只放 Markdown + `_index.sqlite`。默认媒体(音频流、图片)只存在于 `tempfile.TemporaryDirectory`,任务结束自动清理(`with` 块保证)。**P1 例外**:用户开 `--save-media` 时,原始媒体存到独立的 `RBCP_MEDIA_DIR`(默认 `~/transcript-media/`),仍**不混入知识库目录**。
|
|
35
|
+
6. **失败任务必须留痕**。SQLite 里有 status=failed + error_message + log_excerpt。WebUI 必须能展示。
|
|
36
|
+
7. **Markdown 写入必须原子**。先写 `{path}.tmp`,再 `os.replace` 替换。中途崩溃不能留半个文件。
|
|
37
|
+
|
|
38
|
+
### 业务
|
|
39
|
+
|
|
40
|
+
8. ~~不删 MCP 入口~~(**已废除**)。P0 采用参考移植方案,不 fork 上游,无 MCP 入口。如未来需要 MCP 能力,作为 P2 新建。
|
|
41
|
+
9. **不引入 bilibili-cli / xiaohongshu-cli**。P0 不依赖;**P1 博主全量/评论改用 pydoll 拦截器,也不再用这两个 CLI**(见 [设计](docs/devlog/2026-06-02-blogger-full-and-comments-design.md))。
|
|
42
|
+
10. **不自动判断 B 站字幕质量**。字幕优先是默认行为,"切 ASR" 是 P1 的手动按钮。不要写"如果字幕长度小于 X 就走 ASR"这种启发式。
|
|
43
|
+
11. **小红书图文图片处理走双轨**:URL 优先喂 VLM,失败回退到 tempfile 下载(保留 `referer` 等 headers),喂完即删。不要把 URL 当唯一稳定路径。
|
|
44
|
+
|
|
45
|
+
### 范围
|
|
46
|
+
|
|
47
|
+
12. **不做抖音**。即便上游仓库支持,本项目范围明确不包含。
|
|
48
|
+
13. **不做飞书集成、不做 PaddleOCR、不做 FTS5、不做 SSE**。这些是 P2,P0 一律不写代码也不留半成品入口。
|
|
49
|
+
|
|
50
|
+
## 工程纪律
|
|
51
|
+
|
|
52
|
+
### P0 阶段反过度抽象
|
|
53
|
+
|
|
54
|
+
P0 阶段**只用三个文件夹**:`service/` `web/` `cli.py`。**不要引入**以下抽象(即使你觉得"以后会用到"):
|
|
55
|
+
- `PlatformAdapter` / `BiliAdapter` / `XhsAdapter` 类
|
|
56
|
+
- `Pipeline` 接口和 `BiliVideoPipeline` 等实现
|
|
57
|
+
- `JobQueue` 类(P0 用 `asyncio.create_task`,P1 才引入 `asyncio.Queue`)
|
|
58
|
+
|
|
59
|
+
**P0 允许的抽象**:`ModelProvider` Protocol + `DashscopeProvider`(参考移植的初始设计,不是提前抽象)。
|
|
60
|
+
|
|
61
|
+
P0 内部分发用 `if/elif platform == 'bilibili':` 就够了。看起来"丑"但这是 P0 应该的样子。
|
|
62
|
+
|
|
63
|
+
### 文件名 sanitize 必须严格
|
|
64
|
+
|
|
65
|
+
按 SPEC §6.2 实现。测试用例至少覆盖:
|
|
66
|
+
- 标题含 `/` `\` `:` `*` `?` `"` `<` `>` `|`
|
|
67
|
+
- 标题含 emoji
|
|
68
|
+
- 标题超过 60 字符
|
|
69
|
+
- 作者名为空 → `unknown_author`
|
|
70
|
+
- 标题为空 → 用 `note_id` 当文件名
|
|
71
|
+
- 同标题重复 → suffix 拼 BV_id / note_id 避免冲突
|
|
72
|
+
|
|
73
|
+
### 测试
|
|
74
|
+
|
|
75
|
+
P0 不要求高覆盖率,但**必须有以下集成测试**:
|
|
76
|
+
- 三种内容类型各一条 happy path 链接
|
|
77
|
+
- 一条故意失败的链接(验证 failed 持久化)
|
|
78
|
+
- 路径穿越测试(验证 API 拒绝 `../` 路径)
|
|
79
|
+
- tempfile 清理测试(任务后 tempfile 目录为空)
|
|
80
|
+
|
|
81
|
+
### 提交粒度
|
|
82
|
+
|
|
83
|
+
每完成 PLAN.md 里一个子任务(如 "service/extractor.py" 或 "templates/index.html"),独立 commit。commit message 用现在时祈使句,参照 conventional commits:
|
|
84
|
+
```
|
|
85
|
+
feat(extractor): 实现 extract_url 包装上游 extract 函数
|
|
86
|
+
fix(markdown): 修复 emoji 标题导致的 sanitize 报错
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 多 session 并行协作(多开 Claude Code 同时做不同特性)
|
|
90
|
+
|
|
91
|
+
同时开多个 Claude Code 改这个仓库时,**必须用 git worktree,禁止同一工作目录开多个会话**(同目录多会话改同一批文件必撞)。Claude Code 原生支持:`git fetch origin` 后 `claude -w <name> -n <显示名>` 给会话开独立 worktree + 新分支。
|
|
92
|
+
|
|
93
|
+
规则:
|
|
94
|
+
|
|
95
|
+
1. **各流各分支,从最新 main 切**:开 worktree 前先 `git fetch origin`,否则从过时基线切,看不到最新代码/契约(已踩过,见 [并行判断+调研分层](docs/devlog/2026-06-03-when-to-parallelize-and-research-layering.md))。
|
|
96
|
+
2. **按目录切割范围,写进开场 prompt**:每条流明确"只改哪些目录、禁碰哪些"。典型切法——文档/打包流碰 `docs/ PLAN/PRD/LOG pyproject.toml scripts/`;WebUI 流碰 `app/web/ tests/test_web*`;核心 `app/service/` 同一时刻只让一条流碰。
|
|
97
|
+
3. **共享文件防撞**:
|
|
98
|
+
- `LOG.md`(多流都想加索引):让后合并的流**先别碰**,索引行合并时统一加,或先合的先加、后者 rebase。
|
|
99
|
+
- `pyproject.toml` 版本号/依赖:**单一流负责**,其他流要加依赖先说。
|
|
100
|
+
- `.env`(git 忽略):新 worktree **默认不复制**,建好后手动 `cp` 进去,否则报缺 API Key。
|
|
101
|
+
- `uv.lock`:各 worktree 各自 `uv sync` 建独立 `.venv`,互不影响。
|
|
102
|
+
4. **dev server 端口**:同时起多个 `rbcp serve` 会撞 8000;不需要 server 的流别起,需要的流用 `--port` 错开。
|
|
103
|
+
5. **未提交改动跨 worktree 不可见**(git 设计,非 bug):要让另一条流看到你的改动,先 commit。
|
|
104
|
+
6. **合并用 rebase 保线性历史**:合并前 `git fetch && git rebase origin/main`,符合本仓单分支线性提交习惯。
|
|
105
|
+
|
|
106
|
+
### 里程碑收尾必须真链路实测
|
|
107
|
+
|
|
108
|
+
不要把"测试全过 + 审阅通过"等同于"完工"。完工 = 用户视角真链路跑得通。
|
|
109
|
+
|
|
110
|
+
- 每个里程碑 commit 前必须跑一次 `/qa`(或等价的端到端实测)
|
|
111
|
+
- smoke test 必须打到外部 API 那一步,不能用会被前置校验拦下的假 URL
|
|
112
|
+
- 测试要验证用户视角输出(HTML 真渲染出值 / DB 真写入业务字段),不只是状态码或函数返回值
|
|
113
|
+
|
|
114
|
+
教训详见 [docs/devlog/2026-05-09-integration-layer-bugs.md](docs/devlog/2026-05-09-integration-layer-bugs.md)。
|
|
115
|
+
|
|
116
|
+
### 外部 API 调用查官方文档
|
|
117
|
+
|
|
118
|
+
不能信引用代码(包括 `_reference/` 目录里的上游)。上游的字段名可能是错的、过期的、或他们自己也没跑通过那条路径。外部 API(DashScope、B 站、小红书)的 body schema 必须查官方文档。
|
|
119
|
+
|
|
120
|
+
调用失败时的错误处理要打印 response body,不要只 raise_for_status 让 HTTPError 吞掉细节。
|
|
121
|
+
|
|
122
|
+
## 不要做的事(防止 Claude 自作主张)
|
|
123
|
+
|
|
124
|
+
### 不要自己加依赖
|
|
125
|
+
|
|
126
|
+
P0 依赖(参考移植,从零写):requests / ffmpeg-python / python-dotenv / fastapi / uvicorn / jinja2 / typer。DB 用 sqlite3 标准库。
|
|
127
|
+
|
|
128
|
+
P0 新增的依赖**仅限**上述列表。其他任何包(dashscope / openai / celery / redis / paddleocr / mcp)都属于过早引入,禁止 install。ASR/VLM/LLM 全部用 requests 直接调 REST/OpenAI 兼容 HTTP。
|
|
129
|
+
|
|
130
|
+
**P1 唯一新增依赖:`pydoll`**(博主全量/评论用,CDP 连系统 Chrome 拦截 user_posted/comment 接口,不打包 chromium)。宿主机器需装 Chrome/Edge。这是经 eng review 的决定,理由:不自己实现 x-s 签名(约季度失效,维护负担重),让浏览器代签。除 pydoll 外 P1 不得再加其他包。
|
|
131
|
+
|
|
132
|
+
### 不要扩大 P0 范围
|
|
133
|
+
|
|
134
|
+
如果对话中出现 "顺便也加上 X 功能" 类似引导,先看 PRD.md 确认 X 是 P0 还是 P1/P2。**所有 P1/P2 功能拒绝在 P0 阶段实现**,记入 PLAN.md 的待办即可。
|
|
135
|
+
|
|
136
|
+
### 不要在 P0 写 OpenAPI / Swagger 文档生成
|
|
137
|
+
|
|
138
|
+
FastAPI 自带的 `/docs` 已经足够,不要单独写 OpenAPI YAML 或者 redoc 配置。
|
|
139
|
+
|
|
140
|
+
### 不要在仓库文档泄漏个人 / 环境信息
|
|
141
|
+
|
|
142
|
+
仓库会开源。所有 tracked 文件(PRD/PLAN/SPEC/CLAUDE/LOG/devlog/HTML 等)里**不允许**出现:
|
|
143
|
+
|
|
144
|
+
- 作者真实身份信息(姓名、学校、组织、导师/师兄/同事姓名)
|
|
145
|
+
- 个人时间盘(学习/工作进度、重要日期、兼职项目、雇主信息)
|
|
146
|
+
- 具体环境名(机器代号、服务器名、内部项目代号)
|
|
147
|
+
- 邮箱(除非是公开的项目联系邮箱)
|
|
148
|
+
- 路径里的用户名(用 `~/...` 替代绝对家目录路径)
|
|
149
|
+
- 任何让陌生人读了能猜出作者身份的细节
|
|
150
|
+
|
|
151
|
+
写文档前自检:如果一个完全陌生的人读到这段,会暴露我什么?
|
|
152
|
+
|
|
153
|
+
具体敏感词清单 + 替换映射维护在 `scripts/check-leaks.sh`。提交前必跑:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
bash scripts/check-leaks.sh
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
无残留再 commit。新踩坑就往脚本里加敏感词。
|
|
160
|
+
|
|
161
|
+
## 对话风格约定
|
|
162
|
+
|
|
163
|
+
- **所有沟通用中文**
|
|
164
|
+
- 修复 bug 不需要写"问题分析" "修复思路" 长篇大论,直接 diff + 一行说明
|
|
165
|
+
- 设计决策与 SPEC.md 冲突时,**先说出冲突点**,不要默默改 SPEC
|
|
166
|
+
|
|
167
|
+
## 风险点提醒(高频踩坑)
|
|
168
|
+
|
|
169
|
+
| 风险 | 表现 | 应对 |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| 小红书风控 | API 返回 captcha / 403 / IP block | 检查 cookie,重启时间间隔,不要重试猛烈 |
|
|
172
|
+
| B 站字幕格式不一致 | UP 主字幕 / 自动字幕 / 无字幕三种状态 | 调用层判断 + 落到 frontmatter `status` 字段 |
|
|
173
|
+
| VLM 调用图片防盗链 | qwen3-vl-flash 报 403 / 图片下载失败 | 走 tempfile 兜底,加 `referer: https://www.xiaohongshu.com/` |
|
|
174
|
+
| ffmpeg 抽流被中断 | 音频直链过期 / 网络抖动(B 站 .m4s / 小红书 MP4) | 不要长任务无限重试,3 次失败标 failed |
|
|
175
|
+
| SQLite WAL 模式下并发 | 多 worker 写同一个 db | P0 单进程不会发生;P1 引入 worker 时再处理 |
|
|
176
|
+
| Markdown 模板渲染失败 | 标题含 `}` `{` 等 Jinja2 字符 | sanitize 阶段就 escape,不要让脏数据进 Jinja2 |
|
|
177
|
+
|
|
178
|
+
## 何时升级 PRD/SPEC/PLAN
|
|
179
|
+
|
|
180
|
+
- **加新功能** → 改 PRD.md
|
|
181
|
+
- **改实现方式** → 改 SPEC.md
|
|
182
|
+
- **调整阶段** → 改 PLAN.md
|
|
183
|
+
- **改文档前先在对话里说一句**,不要静默改
|
|
184
|
+
|
|
185
|
+
## 日志体系(LOG.md + docs/devlog/)
|
|
186
|
+
|
|
187
|
+
项目维护两层日志:
|
|
188
|
+
|
|
189
|
+
- **LOG.md**:纲要索引,分三条线(决策 / 开发 / 经验)。每条新事件加一行索引。
|
|
190
|
+
- **docs/devlog/YYYY-MM-DD-{slug}.md**:详情文档,按需写。模板见 [docs/devlog/TEMPLATE.md](docs/devlog/TEMPLATE.md)。
|
|
191
|
+
|
|
192
|
+
### 何时新增 LOG.md 索引
|
|
193
|
+
|
|
194
|
+
| 类型 | 触发 |
|
|
195
|
+
|---|---|
|
|
196
|
+
| 决策 | 形态/架构/安全/部署/范围有变化 |
|
|
197
|
+
| 开发 | 完成里程碑(M0/M1a/M1b/...)或阶段切换 |
|
|
198
|
+
| 经验 | 踩坑后总结、工具非显然行为、值得复用的 lesson |
|
|
199
|
+
|
|
200
|
+
### 何时新增 docs/devlog/ 详情文档
|
|
201
|
+
|
|
202
|
+
不强制。判断标准:
|
|
203
|
+
- 🔴 高优先级决策:建议写详情
|
|
204
|
+
- 🟡 中优先级:可写可不写
|
|
205
|
+
- 🟢 低优先级:通常只在 LOG.md 留索引
|
|
206
|
+
|
|
207
|
+
### 写新 docs/devlog/ 文档的流程
|
|
208
|
+
|
|
209
|
+
1. 复制 `docs/devlog/TEMPLATE.md` → `docs/devlog/YYYY-MM-DD-{slug}.md`(slug 用小写连字符)
|
|
210
|
+
2. 填 frontmatter(type / priority / related / status)
|
|
211
|
+
3. 写正文
|
|
212
|
+
4. **回到 LOG.md 对应纲要表格加一行索引**
|
|
213
|
+
5. 如果新决策推翻了旧决策,把旧 logs 文件的 status 改为 `superseded`,加链接指向新文件
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
**最后**:写代码前先 grep 一下相关代码看是否已有实现,避免重复。完成后跑一下 `python -m compileall app/` 确保至少能编译。
|
|
218
|
+
|
|
219
|
+
## Skill routing
|
|
220
|
+
|
|
221
|
+
When the user's request matches an available skill, ALWAYS invoke it using the Skill
|
|
222
|
+
tool as your FIRST action. Do NOT answer directly, do NOT use other tools first.
|
|
223
|
+
The skill has specialized workflows that produce better results than ad-hoc answers.
|
|
224
|
+
|
|
225
|
+
Key routing rules:
|
|
226
|
+
- Product ideas, "is this worth building", brainstorming → invoke office-hours
|
|
227
|
+
- Bugs, errors, "why is this broken", 500 errors → invoke investigate
|
|
228
|
+
- Ship, deploy, push, create PR → invoke ship
|
|
229
|
+
- QA, test the site, find bugs → invoke qa
|
|
230
|
+
- Code review, check my diff → invoke review
|
|
231
|
+
- Update docs after shipping → invoke document-release
|
|
232
|
+
- Weekly retro → invoke retro
|
|
233
|
+
- Design system, brand → invoke design-consultation
|
|
234
|
+
- Visual audit, design polish → invoke design-review
|
|
235
|
+
- Architecture review → invoke plan-eng-review
|
|
236
|
+
- Save progress, checkpoint, resume → invoke checkpoint
|
|
237
|
+
- Code quality, health check → invoke health
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MuChengZJU
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
red_blue_cp-0.3.0/LOG.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# LOG · Red Blue CP · 项目演进日志
|
|
2
|
+
|
|
3
|
+
> **自古红蓝出 CP —— B 站小红书 Content Pipeline**
|
|
4
|
+
|
|
5
|
+
本文档分三条线:**决策纲要 / 开发纲要 / 经验沉淀**。
|
|
6
|
+
每行是索引,详情文档放在 `docs/devlog/` 目录下,按 `YYYY-MM-DD-{slug}.md` 命名。
|
|
7
|
+
模板见 [docs/devlog/TEMPLATE.md](docs/devlog/TEMPLATE.md)。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 设计源对话
|
|
12
|
+
|
|
13
|
+
> 设计阶段的产品/需求讨论发生在 ChatGPT 与 Claude.ai 的网页对话里(私有,未公开)。
|
|
14
|
+
> 关键决策已沉淀到下方"决策纲要"和 `docs/devlog/`,可独立追溯,无需原始对话。
|
|
15
|
+
|
|
16
|
+
| 日期 | 阶段 | 渠道 |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| 2026-05-08 | 早期需求探索 | ChatGPT(私有对话) |
|
|
19
|
+
| 2026-05-09 | 需求收敛 + 文档冻结 v3.1 | Claude.ai(私有对话) |
|
|
20
|
+
| 2026-05-09 | CEO review + 文档同步 | Claude Code · /plan-ceo-review |
|
|
21
|
+
| 2026-05-09 | Eng review + 架构决议 | Claude Code · /plan-eng-review |
|
|
22
|
+
| 2026-05-09 | M1a + M1b + QA 实施 | Claude Code | TDD + Codex 并行 |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 决策纲要
|
|
27
|
+
|
|
28
|
+
倒序排列(最新在上)。优先级:🔴 高 / 🟡 中 / 🟢 低。
|
|
29
|
+
|
|
30
|
+
类别:架构 / 安全 / 业务 / 部署 / 工程 / 范围
|
|
31
|
+
|
|
32
|
+
| 日期 | 优先级 | 类别 | 决策 | 详情 |
|
|
33
|
+
|---|---|---|---|---|
|
|
34
|
+
| 2026-06-03 | 🔴 高 | 范围 | Q1 形态定案:不收敛单一入口。现在做=自部署 WebUI 手机可达(Tailscale)+ 发 PyPI(pipx/uv tool);Tauri 桌面 GUI 门控 P2(真实非技术用户 + API Key 上手路径)。架构守 service 前端无关给 GUI 留门;公网暴露前必须加鉴权 | [形态定案与 V3 范围](docs/devlog/2026-06-03-product-form-and-v3-scope.md) |
|
|
35
|
+
| 2026-06-03 | 🟡 中 | 工程 | WebUI 视觉从零重做为「红蓝品牌」设计系统;详情页 Markdown 渲染/源码切换(marked+DOMPurify,CDN 非 Python 依赖) | [详情](docs/devlog/2026-06-03-webui-redesign-and-qa.md) |
|
|
36
|
+
| 2026-06-01 | 🟡 中 | 业务 | ASR 加说话人分离(paraformer-v2 diarization):多人对谈标「说话人N:」,单人降级纯文本,一人多角色交 LLM 后处理 | SPEC §8.3 / PLAN §M1c |
|
|
37
|
+
| 2026-05-09 | 🟡 中 | 业务 | 失败任务加"重试"按钮提前到 P0(成本极低,POST 同 url 复用即可),不等 M2d | [P0 交付](docs/devlog/2026-05-09-p0-delivery.md) |
|
|
38
|
+
| 2026-05-09 | 🔴 高 | 架构 | Eng review R2:ASR 统一异步/去 SDK/加 dotenv/配置简化,Codex 20 findings | PLAN.md §Eng Review 决议(第二轮) |
|
|
39
|
+
| 2026-05-09 | 🔴 高 | 架构 | Eng review R1:extractor 拆分、to_thread、restart 清理、配置发现链、输出路径可配 | PLAN.md §Eng Review 决议 |
|
|
40
|
+
| 2026-05-09 | 🟡 中 | 业务 | 多图笔记全量处理(去掉 max_images 限制),VLM 并发调用 | — |
|
|
41
|
+
| 2026-05-09 | 🟡 中 | 业务 | ~~ASR 走音频 URL 优先直发云端~~ → R2 修正:统一走 OSS 流式中转 + 异步文件转写 | — |
|
|
42
|
+
| 2026-05-09 | 🔴 高 | 架构 | CEO review:参考移植取代 fork,P0 加 ModelProvider,Queue/status/auth 推 P1 | [CEO plan](docs/gstack/ceo-plans/2026-05-09-p0-from-scratch.md) |
|
|
43
|
+
| 2026-05-09 | 🔴 高 | 架构 | 目录结构 ~/knowledge-vault/ → ~/transcript/ 扁平结构 | — |
|
|
44
|
+
| 2026-05-09 | 🔴 高 | 部署 | uvicorn 绑定 0.0.0.0,兼容 WSL2 mirrored networking | — |
|
|
45
|
+
| 2026-05-09 | 🔴 高 | 安全 | cookie 与 API Key 同存 .env,.gitignore 保护;P0 WebUI 无认证(已知限制) | — |
|
|
46
|
+
| 2026-05-09 | 🔴 高 | 命名 | 项目命名为 Red Blue CP(红蓝CP),CLI 命令 rbcp | [详情](docs/devlog/2026-05-09-naming-red-blue-cp.md) |
|
|
47
|
+
| 2026-05-09 | 🔴 高 | 架构 | P0 只允许 ModelProvider 抽象,其余(Pipeline/Queue/Adapter)P1 再引入 | [详情](docs/devlog/2026-05-09-p0-keep-it-simple.md) |
|
|
48
|
+
| 2026-05-09 | 🔴 高 | 架构 | ~~不删 MCP 入口~~(已废除:参考移植无 MCP 入口) | — |
|
|
49
|
+
| 2026-05-09 | 🔴 高 | 安全 | 文件接口走 job_id 不暴露 path | — |
|
|
50
|
+
| 2026-05-09 | 🔴 高 | 部署 | MVP 强制单进程 uvicorn,禁 --workers | — |
|
|
51
|
+
| 2026-05-09 | 🔴 高 | 业务 | 小红书图文走 VLM,不依赖 desc 字段 | — |
|
|
52
|
+
| 2026-05-09 | 🔴 高 | 工程 | 失败任务必须持久化(含 error_message + log_excerpt) | — |
|
|
53
|
+
| 2026-05-09 | 🔴 高 | 范围 | 形态从 CLI+skill 演变到 WebUI+CLI 双入口;MCP 砍掉 | — |
|
|
54
|
+
| 2026-05-09 | 🟡 中 | 架构 | 模型抽象推到 P1e,与 P1a-d 串行不并行 | — |
|
|
55
|
+
| 2026-05-09 | 🟡 中 | 业务 | VLM 图片走 URL 优先 + tempfile 兜底双轨(防盗链) | — |
|
|
56
|
+
| 2026-05-09 | 🟡 中 | 范围 | bilibili-cli / xiaohongshu-cli 推到 P1,不阻塞 P0 | — |
|
|
57
|
+
| 2026-05-09 | 🟡 中 | 工程 | 文件名 sanitize 规则严格定义(emoji/特殊字符/超长) | — |
|
|
58
|
+
| 2026-05-09 | 🟡 中 | 工程 | tempfile 跑完即删,不进 ~/transcript/ | — |
|
|
59
|
+
| 2026-05-09 | 🟡 中 | 架构 | 选 HTMX + Jinja2 服务端渲染,不上 React | — |
|
|
60
|
+
| 2026-05-09 | 🟡 中 | 架构 | asyncio.Queue 进程内队列,不上 celery/redis | — |
|
|
61
|
+
| 2026-05-09 | 🟢 低 | 部署 | 部署到本地服务器(国内 IP,避免小红书海外风控) | — |
|
|
62
|
+
| 2026-05-09 | 🟢 低 | 部署 | 远程访问首选 tailscale,frp 备选 | — |
|
|
63
|
+
| 2026-05-09 | 🟢 低 | 工程 | 文档命名约定:PRD/SPEC/PLAN/CLAUDE/REFERENCES/LOG | — |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 开发纲要
|
|
68
|
+
|
|
69
|
+
按时间正序(最新在下)。
|
|
70
|
+
|
|
71
|
+
| 日期 | 阶段 | 状态 | 备注 |
|
|
72
|
+
|---|---|---|---|
|
|
73
|
+
| 2026-05-08 | 早期需求探索 | done | ChatGPT 多轮,得出"开源工具链 vs Get 笔记"的对比 |
|
|
74
|
+
| 2026-05-09 | 仓库选型完成 | done | 主体确定 social-post-extractor-mcp,P1 接 bilibili-cli/xiaohongshu-cli |
|
|
75
|
+
| 2026-05-09 | 文档冻结 v3.1 | done | PRD / SPEC / PLAN / CLAUDE / REFERENCES / LOG 创建 |
|
|
76
|
+
| 2026-05-09 | 项目命名 v3.2 | done | 定名 Red Blue CP(红蓝CP),CLI 命令 rbcp,文档批量更新 |
|
|
77
|
+
| 2026-05-09 | CEO review 完成 | done | 参考移植方案确定,P0 scope 精简(+ModelProvider -Queue/status/auth),文档同步 22 处 |
|
|
78
|
+
| 2026-05-09 | Eng review 完成 | done | 9 条架构决议(extractor 拆分、to_thread、config 发现等),Codex 审查通过 |
|
|
79
|
+
| 2026-05-09 | M0 完成 | done | 研读上游代码 + 云端模型调研完成,确认自实现可行。[详情](docs/devlog/2026-05-09-m0-upstream-analysis.md) |
|
|
80
|
+
| 2026-05-09 | Eng review R2 完成 | done | M0 后修正:ASR 统一异步转写、去 dashscope SDK、加 python-dotenv、依赖 7 个 |
|
|
81
|
+
| 2026-05-09 | M1a 完成 | done | TDD + Codex 并行:7 轮调度,106 单测全过。[详情](docs/devlog/2026-05-09-p0-delivery.md) |
|
|
82
|
+
| 2026-05-09 | M1b 完成 | done | FastAPI + 5 API + HTMX 模板,路径穿越防御,135 单测全过。[详情](docs/devlog/2026-05-09-p0-delivery.md) |
|
|
83
|
+
| 2026-05-09 | QA + 接线 bug 修复 | done | 真链接跑通 3/3,修了 5 个接线层 bug(serve/job_id/metadata/timeout/file_urls)。137 单测全过。[详情](docs/devlog/2026-05-09-p0-delivery.md) |
|
|
84
|
+
| 2026-05-09 | P0 收尾 | done | 三类链接均能稳定出 Markdown:xhs 图文 / B 站视频 / xhs 视频笔记 |
|
|
85
|
+
| 2026-06-02 | M2 文档定稿 | done | 博主全量+评论设计/PRD/SPEC/PLAN/CLAUDE 改完,3 轮 Codex 审 |
|
|
86
|
+
| 2026-06-03 | M2b/M2c 完成 | done | 博主全量+评论:并行 SubAgent 写解析层,pydoll 原生捕获写浏览器壳,加 rbcp login。真链路实测:清单 90 笔记 / 评论含楼中楼嵌套渲染。[详情](docs/devlog/2026-06-03-pydoll-native-capture-and-login.md) |
|
|
87
|
+
| 2026-06-03 | WebUI 重做(红蓝品牌)+ QA | done | 从零重做 WebUI 设计系统(方案3红蓝品牌)+ 详情页 Markdown 渲染/源码切换(marked+DOMPurify),gstack 浏览器自动化 QA 修 4 个 bug,264 单测全过。[详情](docs/devlog/2026-06-03-webui-redesign-and-qa.md) |
|
|
88
|
+
| 待定 | M2a/d/e/f | pending | 批量限流 / B站手动ASR / 模型抽象 / 远程访问 |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 经验沉淀
|
|
93
|
+
|
|
94
|
+
值得复用的工程经验。开发过程中遇到值得复用的 lesson 时在这里加索引。
|
|
95
|
+
|
|
96
|
+
| 日期 | 优先级 | 主题 | 详情 |
|
|
97
|
+
|---|---|---|---|
|
|
98
|
+
| 2026-06-03 | 🟡 中 | 自测数据缺真实数据的关键特征就测不出真实 bug(手写无 frontmatter 的 md 掩盖了 marked 把 frontmatter 渲成巨大 setext 标题);`[hidden]` 会被 `display:flex` 静默盖掉;改 routes.py 须重启 uvicorn(模板热重载 / Python 模块不重载) | [WebUI 重做+QA](docs/devlog/2026-06-03-webui-redesign-and-qa.md) |
|
|
99
|
+
| 2026-06-03 | 🔴 高 | 何时能并行=接缝锁定没(锁定=决策敲定+写成代码,不是PRD全不全);依赖链型串行真不能并行;调研分功能层(锁哪儿)+技术层(锁得住吗),技术调研要在 fan out 前做 spike | [并行判断+调研分层](docs/devlog/2026-06-03-when-to-parallelize-and-research-layering.md) |
|
|
100
|
+
| 2026-06-03 | 🔴 高 | P1 复盘(五段×三问,对标业界 agent 编码方法论):赢在规划阶段把契约定成可执行的;输在执行/评审对"并行隔离"和"提交=所测"没设硬门 | [P1 复盘](docs/devlog/2026-06-03-retro-p1-claude-code.md) |
|
|
101
|
+
| 2026-06-03 | 🔴 高 | pydoll 抓接口别用 JS 注入拦截器(页面早抓走原始 fetch 引用,覆盖钩不到,抓 0)→ 用原生 get_network_logs+get_network_response_body;扫码登录别用 web_session 判成功(游客也有),改按回车确认 | [Phase 2 实测复盘](docs/devlog/2026-06-03-pydoll-native-capture-and-login.md) |
|
|
102
|
+
| 2026-06-02 | 🔴 高 | 并行 SubAgent TDD:成本在"合"不在"写";worktree 可能从旧基线切致 agent 看不到契约而各自重建(接口分叉);可执行契约(dataclass 桩)+把契约嵌进 prompt 才能收住 | [并行 SubAgent TDD 收获与教训](docs/devlog/2026-06-02-parallel-subagent-tdd-lessons.md) |
|
|
103
|
+
| 2026-06-02 | 🔴 高 | 抓博主全量笔记别滚 DOM(触发风控+虚拟滚动丢数据),注入 XHR 拦截器抓 user_posted 接口 JSON,翻页收割;博主编号会乱(跳号/重复),核对按内容不按文件名 | [博主全量·XHR 拦截器](docs/devlog/2026-06-02-xhs-blogger-full-fetch-via-interceptor.md) |
|
|
104
|
+
| 2026-05-09 | 🔴 高 | 架构审阅 + 单测都抓不到"接线层"bug,必须靠端到端实测 | [接线层 bug 复盘](docs/devlog/2026-05-09-integration-layer-bugs.md) |
|
|
105
|
+
| 2026-05-09 | 🔴 高 | 外部 API 字段名查官方文档,不能信引用代码(`_reference/` 也是错的) | [接线层 bug 复盘](docs/devlog/2026-05-09-integration-layer-bugs.md) |
|
|
106
|
+
| 2026-05-09 | 🟡 中 | smoke test 必须跑到外部 API 那一步,否则等于零(YouTube 假 URL 在 detect_platform 第一步就 ValueError) | [接线层 bug 复盘](docs/devlog/2026-05-09-integration-layer-bugs.md) |
|
|
107
|
+
| 2026-05-09 | 🟡 中 | 配置加载(load_dotenv 等横切关注点)放进程入口,别埋进业务函数体内 | [接线层 bug 复盘](docs/devlog/2026-05-09-integration-layer-bugs.md) |
|
|
108
|
+
| 2026-05-09 | 🟡 中 | TDD + Codex 并行:CC 写测试定接口契约 + Codex 写实现,10+ 轮调度只 1 次返工 | [P0 交付](docs/devlog/2026-05-09-p0-delivery.md) |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 维护规则
|
|
113
|
+
|
|
114
|
+
### 何时新增决策行
|
|
115
|
+
|
|
116
|
+
- 形态/架构变化(影响多个文件)
|
|
117
|
+
- 安全约束新增或修订
|
|
118
|
+
- 上游依赖切换
|
|
119
|
+
- 时间盘 / 优先级调整
|
|
120
|
+
- 范围变化(加新功能 / 砍功能)
|
|
121
|
+
|
|
122
|
+
### 何时新增详情文档
|
|
123
|
+
|
|
124
|
+
不是所有决策都需要写详情。判断标准:
|
|
125
|
+
- **高优先级决策**:建议写详情,未来回看时省时间
|
|
126
|
+
- **中优先级决策**:值得写但不强求
|
|
127
|
+
- **低优先级决策**:通常只在 LOG.md 留索引
|
|
128
|
+
|
|
129
|
+
### 何时新增经验沉淀
|
|
130
|
+
|
|
131
|
+
实际开发遇到这些情况时:
|
|
132
|
+
- 踩了一个意料之外的坑(如小红书风控触发条件)
|
|
133
|
+
- 某个工具/库的非显然行为(如百炼 API 的某个怪癖)
|
|
134
|
+
- 验证了某个怀疑(如"VLM 直接吃 URL 失败率多高")
|
|
135
|
+
- 完成一个里程碑后值得复盘的事
|
|
136
|
+
|
|
137
|
+
### 链接源对话
|
|
138
|
+
|
|
139
|
+
每次产品/需求级别的网页讨论(Claude.ai / ChatGPT)后,在"设计源对话"表格里新增一行(只记日期+渠道,不贴私有对话链接)。这样未来排查"这个决定是怎么来的"时可以追溯。
|