Files
dsh_ai1net_server/归档/skills-清理-20261007/content-source-governance/SKILL.md
T
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 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/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

247 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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」的假象,容易误判成内容缺失。