- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次) - .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…), 目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪 - .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/) - .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*) - .gitignore 补:备份件(*.bak-*) - 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
247 lines
19 KiB
Markdown
247 lines
19 KiB
Markdown
---
|
||
name: content-source-governance
|
||
description: 给「定时/周期性自动生成内容」的项目建一套信源治理层——治「AI 每天自动生成日报/周报,但信源越用越水、数字对不上、主角跑偏(该报小项目却全是巨头)、覆盖写把历史产物冲掉、手机上没法看」。当用户说「这个日报/周报要每天自动生成」「信源质量不行」「为什么全是巨头新闻」「再找些更垂直的源」「加个信息源」「生成新的别把历史的删了」「移动端体验不好」时触发。核心 = 治理层与检索层双文件分工 + 信源必先实测再入册 + 「主体分层」决定谁是头条 + 展示数字与注册表条目数机械核对 + 归档只增不减 + 移动端用真机视口量化而非猜测。
|
||
version: 1.2.0
|
||
updated_at: 2026-09-28
|
||
agent_created: true
|
||
---
|
||
|
||
# content-source-governance — 周期性内容项目的信源治理
|
||
|
||
一个人每天让 AI 自动生成一份日报,**三周后一定会出现的五个病**:
|
||
|
||
1. **信源越用越水**——第一周引 Bloomberg,第三周引中文聚合号,第五周引内容农场。
|
||
2. **主角跑偏**——想报的是「个人开发者小项目」,实际全是 OpenAI、Anthropic 的融资新闻,因为巨头新闻**最好搜、最多、最省事**。
|
||
3. **数字对不上**——首屏写「28 条」,页脚写「25 条」,某个分区徽标写「11 条」但里面只有 5 张卡。
|
||
4. **历史被覆盖**——流程里全是覆盖写,用户开始担心「生成新的会不会把旧的删了」;这类担心一旦出现,信任就已经受损了。
|
||
5. **手机上没法看**——用户主要在手机上打开,而版式是按桌面设计的:宽表被压成窄竖条、按钮小到点不准、导航横滑却看不出能滑。
|
||
|
||
本技能给的是治这五个病的固定结构,不依赖具体项目。
|
||
|
||
## 一、两个文件,职责必须分开
|
||
|
||
放两份文件在项目根目录,**不要让一份文件同时干两件事**:
|
||
|
||
| 文件 | 角色 | 装什么 | 谁读 |
|
||
|---|---|---|---|
|
||
| `数据源注册表.md` | **治理层** | 准入判据 / 剔除判据 / A·B·C 白名单 / 黑名单 / 结构要求(地域、主体) / 每次执行的治理动作 / 变更日志 | 每日任务第一步必读;**冲突时以它为准** |
|
||
| `信源地图_xxx.md` | **检索层** | 去哪找、怎么用、什么口径、访问方式(直连 or 浏览器)、避坑清单、**每日检索起手式** | 每日任务第一步必读 |
|
||
|
||
为什么必须分开:注册表会被每日任务**回写**(新增源、拉黑源、记变更日志),信源地图基本只读、越写越厚。混在一起会让每日任务在改「操作方法」时误改「判据」。
|
||
|
||
注册表头部固定一行 `> 最后更新日期:...(本次改了什么)`——一眼看出规则版本。
|
||
|
||
## 二、信源入册的硬纪律:先实测,再入册
|
||
|
||
**绝不采信搜索摘要里的域名和描述。** 搜索摘要会把「不存在的站」「早已死的站」写得像活的。
|
||
|
||
固定动作(每个候选源都做一遍):
|
||
|
||
```bash
|
||
probe() { code=$(curl -s -m 12 -o /dev/null -w "%{http_code}" -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" "$1" 2>/dev/null); \
|
||
t=$(curl -s -m 12 -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" "$1" 2>/dev/null | grep -o -i "<title>[^<]*</title>" | head -1 | sed 's/<[^>]*>//g' | cut -c1-64); \
|
||
printf " %-46s HTTP %-4s %s\n" "$1" "$code" "$t"; }
|
||
```
|
||
|
||
按状态码处置:
|
||
|
||
| 结果 | 处置 |
|
||
|---|---|
|
||
| **200** | 入册,注明口径与访问方式 |
|
||
| **403**(Cloudflare「Just a moment...」) | 站点真实存在但直连被反爬 → **在册并注明「须走浏览器通道」**,不要写「不可用」 |
|
||
| **526 / SSL 握手失败** | 站方 TLS 配置故障 → 注明「实测不可用」 |
|
||
| **000**(DNS/连接失败) | 本机不可达。**先判断是不是被墙或需 JS**;Reddit、V2EX 这类站正常浏览器能开 → 写「须浏览器通道」,不要误判为死站 |
|
||
| **404** | 该路径不存在,试根域名;根域名也 404 → 丢弃 |
|
||
|
||
**附带纪律**:搜索摘要里出现、但探测不解析的域名(如 `revenuejourneys.com`、`indiehacker.directory`)→ **直接不入册**,在变更日志里记一笔「未验证,不入册」。这条纪律本身就是最有价值的产出之一——它挡住了 80% 的假源。
|
||
|
||
## 三、主体分层:决定「谁是头条」的唯一杠杆
|
||
|
||
周期内容跑歪的根因是**采集优先级没成文**。搜索天然偏好巨头新闻,所以必须把「谁是主角」写成硬规则,而不是靠当期恰好如此。
|
||
|
||
在注册表里开一节「主体结构要求」,把主体**从最小往大分层**,每层给判定 + 配额 + 记账口径。以「AI 变现日报」为例(可直接照搬结构,换掉内容):
|
||
|
||
| 层 | 判定 | 配额 |
|
||
|---|---|---|
|
||
| **1A 微型项目**(最先找) | ≤2 人 · 无雇员 · **收入从 0 起(累计 <$10k 或 MRR <$1k 也照收,不设金额门槛)** · 上线 ≤12 个月 · 单点网页/插件/小工具/模板 · **有没有 AI 能力不是必要条件** | 「验证案例」≥1 条;头条能找到就优先放 |
|
||
| **1B 个人 / 小团队** | 独立开发者、一人公司、2–20 人小团队、≤50 人初创、开源作者。**团队规模优先于金额**——几人团队做到千万美元 ARR 仍算主线 | 占主体篇幅 |
|
||
| **2 巨头 / 大厂** | 明确的巨头清单 + 员工 >1000 人公司的整体财报或战略级动作 + 巨头间并购 | **只进末尾「新闻速览」分区,≤ 总条数 25%,不得进头条,不得作收入样本** |
|
||
|
||
**四条必须一起写进去的反直觉规则**(缺一条,规则就会被绕过):
|
||
|
||
- **金额小不构成降级理由**:¥2000/月的插件、$400/三周的小站,都是合格头条候选。
|
||
- **找不到就如实说明,不得用巨头顶位**:写明「今日未采到达标的小项目」并列出检索过的源。
|
||
- **不得把「作品集收录」「榜单排名」当业绩**:上榜 ≠ 有收入。
|
||
- **「0 收入」样本不是废料但要配对**:可进「雷区预警」,但必须与已赚到钱的样本同篇呈现,不得整篇只有失败样本。
|
||
|
||
记账口径也按同一分层写死,例如四段:`微型项目 X 条 · 个人/小团队 Y 条 · 中小创业公司 Z 条 · 巨头 W 条`,并要求每期变更日志记录。
|
||
|
||
## 四、越小的主体,越不能靠媒体——必须去「没有记者」的地方
|
||
|
||
这是本技能最实用的一条经验。**微型项目不会有任何媒体报道**,靠新闻搜索永远采不到。已实测可用的入口类型(换题材时替换具体站点):
|
||
|
||
| 类型 | 例子 | 给什么 |
|
||
|---|---|---|
|
||
| **作品集 / 展示墙** | `madewithlovable.com`、`madewithbolt.com`、`vibecoded.directory` | 个人搭出来的成品清单(含作者名)——**⛔ 无收入数字,纯发现用** |
|
||
| **微型首发榜** | `fazier.com`、`tinylaunch.com`、`uneed.best`、`betalist.com` | 最近 1–2 天新上线的小项目与首发定价 |
|
||
| **逐日流水账** | `dev.to/t/buildinpublic`、`dev.to/t/sideproject`、Reddit `r/SideProject` | 「第一位付费用户」「$0 → $1」的一手实录,最诚实 |
|
||
| **中文社区域** | V2EX(分享创造 / 副业)、即刻(独立开发者圈) | 中文极小额样本主产地 |
|
||
| **二次汇总(省时间)** | `txtmix.com`「AI 副业午报」(日更)、`neodrop.ai` 收入周报(周更) | 别人已替你从 Reddit/V2EX 摘好中文摘要**并附原文链接** → **只作线索,引用必须回指原文** |
|
||
|
||
**写作纪律**:自述类源(社区、作品集、汇总站)**只能用于「发现项目」**;入报数字必须回访作者带日期的原始披露或其支付侧页面;回访不到就标「来源:XXX 自述(平台 + 链接),未独立核实」,只做配角。
|
||
|
||
**顺带一个副产品**:把「已核实样本清单」写进信源地图(项目 · 主体 · 形态 · 自述数字 · 原文),每天任务就有一把**「什么量级才算这个层」的对照尺**,避免把 $10k MRR 当小项目、把 $20 当业绩。
|
||
|
||
## 五、展示数字必须与注册表机械核对
|
||
|
||
只要有「信源健康度 4 个数字」这类展示位,就一定会在某天开始对不上(改注册表时容易忘)。
|
||
|
||
**先定义口径,再写脚本核**:
|
||
|
||
> 计数口径 = 该等级列表的**条目数**(表格一行 = 1 条;一个列表项 = 1 条;同一行内并列的多个站点合并计 1)
|
||
|
||
然后每次改完必跑:
|
||
|
||
```python
|
||
import re
|
||
t = open('数据源注册表.md', encoding='utf-8').read()
|
||
def rows(s, e):
|
||
seg = t.split(s)[1].split(e)[0]
|
||
L = [l for l in seg.split('\n') if l.strip().startswith('|')]
|
||
return [l for l in L if not re.match(r'^\|\s*-+', l.strip()) and '| 源 |' not in l]
|
||
real = {'A 级': len(rows('### A 级','### B 级')), 'B 级': len(rows('### B 级','### C 级')),
|
||
'C 级': len([l for l in t.split('### C 级')[1].split('## 四、黑名单')[0].split('\n') if l.strip().startswith('- ')]),
|
||
'黑名单': len(rows('## 四、黑名单','## 五、'))}
|
||
h = open('index.html', encoding='utf-8').read()
|
||
idx = dict((m.group(2).split(' ·')[0], m.group(1)) for m in re.finditer(r'<div class="n">(\d+)</div><div class="l">([^<]+)</div>', h))
|
||
for k, v in real.items():
|
||
print(f"{k} 注册表 {v} index {idx.get(k)} {'✅' if str(v)==str(idx.get(k)) else '❌'}")
|
||
```
|
||
|
||
**同时必须把这句写进每日任务的 prompt**:「该四格必须等于注册表各等级的实际条目数,用脚本核对,**禁止凭印象填**」——否则明天的自动执行又会凭感觉改回去。
|
||
|
||
同类计数口径(条数 = 各内容分区卡片数之和、行动块不计条、页脚总数 = 首屏总数 = 各分区徽标之和)也要一次定义清楚并写进任务,否则历史遗留的「验证案例 11 条但只有 7 张卡」会一直存在。
|
||
|
||
## 六、每日任务的 prompt 怎么写
|
||
|
||
`automation_update` 的 prompt 要**自包含**(未来执行看不到本次对话),固定五段结构:
|
||
|
||
```
|
||
【第一步 · 读治理与检索文件】精确路径 + 本次最该看的那一节
|
||
【第二步 · 采集】分轮次,最小主体在最前(第 0 轮),逐轮给站点与英文关键词
|
||
【第三步 · 生成 HTML】占位符清单 + 分区顺序 + 计数口径(自检一遍)
|
||
【第四步 · 落盘】写哪几个文件、哪个锚点插行、哪个数字要脚本核对
|
||
【第五步 · 源治理】新增/拉黑/升降级都要回写,变更日志记什么(含分布)
|
||
【硬约束】红线清单
|
||
```
|
||
|
||
三条容易漏的硬约束,务必写上:
|
||
|
||
- **不得修改模板文件**(它只作版式参考);发现版式与最近一期不一致就**先问,不要擅自改版**。
|
||
- **`present_files` 只传 `.html`**——预览面板只服务 HTML,`.md` 会显示「文件已被删除」,让用户以为文件丢了。
|
||
- 完成后回复里要给**一句话摘要 + 分布统计**(信源地域分布、主体分布、本期新采用的源),让用户能一眼验证规则生效。
|
||
|
||
## 七、变更日志写什么
|
||
|
||
每期一条,倒序(最新在最上),固定含:
|
||
|
||
- **日期 + 第几次执行**
|
||
- **新增 / 剔除 / 降级**了哪些源,各自理由
|
||
- **本期实际采用的信源**
|
||
- **本期分布**:信源地域(海外 X / 国内 Y)+ 主体分层(四段)
|
||
- 规则修订时另起一条,写「**起因**(谁提的什么反馈)+ **改动清单** + **本期实测结论**」
|
||
|
||
规则修订条目里**必须记起因的原话**。否则三个月后没人知道那条看似奇怪的配额是怎么来的,很容易被当成冗余删掉——然后病就复发了。
|
||
|
||
## 八、产物保护:归档只增不减(第四个病)
|
||
|
||
「每天生成」意味着流程里有**覆盖写**。用户迟早会问一句「生成新的别把历史的删了啊」——**这句话一旦出现,说明之前只是恰好没删,而不是规则上不能删。** 所以要在还没出事的时候就把规则写死。
|
||
|
||
核查顺序:先证明历史**现在没丢**(列出文件、逐条比 md5、确认索引行与链接可解析),再补规则。**不要一被问就道歉并重写流程**——先拿证据说话,很可能什么都没丢;真正缺的只是「明令禁止删除」这条成文约束。
|
||
|
||
三层落地:
|
||
|
||
**① 任务层**——prompt 里写死两件事:
|
||
|
||
- **开跑前记基线**:归档文件数 `N_before` + 文件名清单、索引归档行数 `R_before` + 日期集合。
|
||
- **执行后双向校验**:归档文件数必须 = `N_before + 1`(同日重跑 = `N_before`),索引日期集合**只增不减**;不符 → **立即停止写入并报告差异,不要继续动文件**。
|
||
|
||
**② 治理层**——给每个路径写明「允许写 / 禁止写」,别只写一句「不要删历史」:
|
||
|
||
| 典型路径 | 允许 | 禁止 |
|
||
|---|---|---|
|
||
| `archive/{date}.html` | 新建当日文件;同日重跑可覆盖 | 删除、覆盖**非当日**历史文件 |
|
||
| `latest.html` | 覆盖(它是「最新一期副本」;**覆盖前必须确认当期已先写入 archive**) | 在 archive 写入成功前覆盖 |
|
||
| `index.html` | 锚点之间插入/更新当日行;刷新统计数字 | 删除历史行、清空锚点区间、**整表重写** |
|
||
| 历史留档 / 模板 / 治理文件 | 只追加(变更日志) | 任何删除或改写 |
|
||
|
||
**③ 恢复网**——一个只增不减的备份目录:每日在校验**通过之后**,只把 archive 里尚不存在于备份的文件复制过去(**只复制、不删除**)。这样任何一次生成异常都有回退源。
|
||
|
||
两条必须点明的语义,否则规则会被绕过:
|
||
|
||
- `latest.html` 是**副本**,允许覆盖;历史由 `archive/` 承载。**先写 archive、后覆盖 latest**,顺序颠倒就永久丢一期。
|
||
- **禁止凭记忆重建历史**——发现缺失只能从备份复制取回,取不回就如实报告。模型的「补一份出来」会制造比缺失更糟的问题:一份看不出是假的假历史。
|
||
|
||
**④ 版本控制**——如果项目目录在 git 仓库里,把产物纳入跟踪是最强的一层(完整历史 + 可 diff + 可恢复到任意一天)。四条实操纪律:
|
||
|
||
- **先查再动**:`git check-ignore -v <路径>` 确认它是「被忽略」还是「仅仅未跟踪」——新建目录常常只是没人 add 过,不是被刻意排除。是否纳入属于用户的仓库约定,**先问一句**。
|
||
- **按路径提交,禁止 `git add -A` / `git add .`**:日报项目往往和别的代码同仓,通配 add 会把无关改动一起提交。用 `git add "<日报目录>"`。
|
||
- **只提交、不推送**:`git push` 由用户决定。
|
||
- **固定换行符**:Windows 上 `core.autocrlf=true` 时加一条 `.gitattributes` 把产物目录钉成 `text eol=lf`,否则 checkout 后文件变 CRLF,会出现「内容没变却显示已修改」的幻影差异,干扰每日校验。
|
||
|
||
自动化里这一步要写成**可跳过**:git 未配置 / 报冲突就跳过并说明,**绝不允许在自动化里跑 `git reset`、`git checkout --`、`git clean`**——那反而是最可能真正删掉东西的操作。
|
||
|
||
另外,同仓里如果存在**旧副本目录**(迁移前的源目录),要在任务 prompt 里明确写「唯一有效目录是 X,Y 已停用、不要写它」。否则未来某次执行可能误写旧路径,产出两份互不同步的日报。**不要直接删除旧副本**——加一份说明文件标明「已迁移 + 当前位置 + 缺什么」更安全,也顺带消除「打开旧版以为历史丢失」的误判。
|
||
|
||
## 九、移动端:别猜,用真机视口量化
|
||
|
||
周期性内容的产物**多半是在手机上看**。用户说「移动端体验不好」时,**不要凭 CSS 打补丁**——先量化,因为最难的问题往往不在你以为的地方。
|
||
|
||
### 量化体检(跑这一段,问题基本全暴露)
|
||
|
||
用真机逻辑视口(如 iPhone 393×852)加载页面,然后逐项取数:
|
||
|
||
```js
|
||
// 视口与溢出
|
||
innerWidth; document.documentElement.scrollWidth - innerWidth; // 必须 ≤ 0
|
||
// 逐元素查溢出
|
||
document.querySelectorAll('*').forEach(el => { /* getBoundingClientRect().right > innerWidth */ });
|
||
// 点击目标
|
||
[...document.querySelectorAll('a,button')].map(el => el.getBoundingClientRect()); // 高 <44px 不达标
|
||
// 字号
|
||
getComputedStyle(el).fontSize; // 正文 <15px 偏小
|
||
// 粘性导航遮挡
|
||
getComputedStyle(section).scrollMarginTop >= topnav.getBoundingClientRect().height;
|
||
// 表格列是否被压垮(横向布局在窄屏的头号杀手)
|
||
[...document.querySelectorAll('th')].map(th => th.getBoundingClientRect().width);
|
||
```
|
||
|
||
**踩坑提醒**:CDP 设视口要在建 tab **之后**再 `Emulation.setDeviceMetricsOverride`,否则会失效、测出的是旧宽度——那样得到的结论会偏乐观。
|
||
|
||
### 实测最容易暴露的两类问题
|
||
|
||
**① 宽表被压成窄竖条。** 表格在窄屏不会溢出,它会**把列挤扁**。实测遇到过:摘要列被压到只剩 80px,中文每行 5–6 字,单行高 **428px**(占半屏),几行就撑满整页。这类问题从「有没有横向滚动条」完全看不出来。
|
||
|
||
**修法**:`@media` 里把 `table/tr/td` 重排为卡片(`display:block/grid`),**不要改 HTML 结构**——如果项目靠注释锚点在表格里插行(如 `ARCHIVE_ROWS_START/END`),换成 div 卡片会直接破坏插入协议。纯 CSS 重排既解决问题又保住协议。
|
||
|
||
**② 横向可滚的导航,没有「可滑」的暗示。** 7 个按钮在 393px 下必然装不下。若只有 `overflow-x:auto`,用户会以为按钮就这几个。要补三件事:
|
||
|
||
- **右侧渐隐**:`mask-image:linear-gradient(90deg,#000 calc(100% - 30px),transparent)`
|
||
- **激活项自动滚入视野**:手动点的按钮要滚进来,**scrollspy 高亮时也要**(否则高亮的那个在屏幕外,等于没高亮);只滚横向容器,别动页面纵向
|
||
- **品牌区瘦身**:长标题在小屏只留图标,能省出近百像素
|
||
|
||
### 两条产品判断(不只是技术)
|
||
|
||
- **别把信息截断成省略号**。来源、口径、时间窗是这类日报的**可信度依据**,`text-overflow:ellipsis` 把它变成「(某口径)…」等于把立论依据藏起来。小屏上应允许换行。
|
||
- **首屏别只放装饰**。hero 占 62% 屏时,用户看不到任何内容。压缩 hero 与统计卡的间距,让首屏露出第一个分区标题。
|
||
|
||
### 改完必做三项回归
|
||
|
||
1. **只改样式**:比对「去掉 `<style>`/`<script>` 后正文完全一致」——证明没动内容。再加标签开闭差、CSS 花括号差为 0、分区数与卡片数不变。
|
||
2. **桌面端不回归**:1440px 下再测一遍(卡片多列、宽表仍是 `display:table`、导航不需横滚)。
|
||
3. **多份产物一致性**:模板 + 最新一期 + 各期归档 + 备份,`@media` 块必须**逐字节一致**(md5 校验)。否则改一次只在当期生效,历史各期样式各不相同。用脚本批量替换 + 统一校验,别手改。
|
||
|
||
最后把量化清单写进每日任务的**自检项**:新一期生成后要跑一遍并报数。否则下一次生成又把 `overflow-x`、`scroll-margin-top` 这些细节丢回去。
|
||
|
||
另外,截图取证要**等动画结束**——入场动画进行中抓图会得到「标题半透明、计数为 0」的假象,容易误判成内容缺失。
|