# 8011 desktop-html 站点维护规则（Agent Skill）

> **本文件就是 Skill**：任何被授权维护 `http://8.130.85.149:8011/` 的 AI Agent，读完本页即可按 SOP 完成新文章的归类收录。
> 版本 v1.1 · 2026-10-19 · 站长：杭州 · 维护 Agent：香农（清言 AgentMore） · <br>v1.1 变更：新增 §8 构建器规则 / §9 审计经验；§5 精装卡片主路径改为 build.py
> 人机友好版：<http://8.130.85.149:8011/工具/分类规则.html>

---

## 0. 一句话流程

**新文章 → 按第 2 节决策树选目录 → 文件放入该目录（同名侧车同迁）→ 完成。**
首页会自动收录新文件并自动提取文章 `<title>` 作为卡片标题（零配置路径）。
进阶可选：为 `index.html` 补 META 条目获得精装卡片（含简介与标签，见第 5 节）。

## 1. 站点架构速览

| 组件 | 位置 / 说明 |
|---|---|
| Web 服务器 | nginx 1.14.1，配置 `/etc/nginx/conf.d/desktop-html.conf`，端口 8011 |
| 站点根 | `/var/www/desktop-html/` |
| 首页机制 | `index.html` 逐分类 `fetch /listing/<目录>/`（nginx autoindex JSON，非递归）→ 渲染卡片 |
| 标题来源 | 优先查内嵌 `META`（key = `"目录/文件名"`）；**查不到时自动 fetch 该文件并提取 `<title>` 兜底**，标签显示「自动收录」 |
| 兜底区 | 根目录散落的 `.html` 显示在「📥 未归类」分区——**放根目录不会丢，只是未归类** |
| 旧链兼容 | nginx 回退规则：根级 `.html` 未命中时按 知乎→投资→调研→工具→其他 顺序回退，改造前分享的扁平直链全部仍然 200 |
| 子站（勿动） | `fq-book/`（电子书）、`grid-data/`（电网地图）、`parking-viz/`（车位图）、`/quota`（反代 8471）、`share.js`/`track.js`（分享与统计） |
| 备份惯例 | 服务器快照放 `/var/www/backups/`；永久归档放 `oss://agent-kanban/backup/desktop-html/` |

**分类目录**（首页按此优先级展示）：`知乎/` `投资/` `调研/` `工具/` `其他/` `数据/`（数据目录不显示卡片）

## 2. 分类决策树（按判断顺序执行）

> **核心原则：按文章主旨内容分类，而非来源平台。** 冲突时按站长主权排序：知乎 > 投资 > 调研 > 工具 > 其他。

1. **内容主体是知乎**（问答/回答汇总、知乎人物调研、知乎热点观察）→ `知乎/`
2. **主旨是投资理财**（行情日报、量化/回测、ETF 与基金、仓位与纪律、投资类播客如知行小酒馆、大宗商品事件驱动）→ `投资/`
   - ⚠️ 特例：知乎来源但主题为 A股/投资机会/预期差方法论 → `投资/`（先例：`ashare-zhihu-*`、`zhihu_invest_q2`、`zhihu_expectation_q4`、`龙头18868`）
3. **深度调研报告**（行业/技术/公司/地缘/产品拆解/项目文档/论文翻译/事件全景解析）→ `调研/`
4. **可复用的交互工具与 SOP**（地图类、数据可视化工具、工作流 SOP、工具横向评测）→ `工具/`
5. **生活/娱乐/影视人物档案** → `其他/`
6. **纯数据附件**（json/csv/xlsx/md 且无同名 html 引用）→ `数据/`（不在首页展示）
7. **判断不准** → 放根目录，让「未归类」兜底。**宁缺勿错。**

## 3. 文件命名与侧车规则

- 推荐命名：中文描述性文件名或 `slug-YYYY-MM-DD.html`；**避免空格**（用连字符）；日期后缀放末尾
- 文件内 `<title>` **必须写完整中文标题**（这是自动收录时卡片标题的来源，也是唯一必做的"内容编辑"）
- 同名侧车文件（`.json`/`.md`/`.js`，如 `foo.html` + `foo_data.js`）**必须与 html 同目录**（相对引用会被 fetch）
- 不新增一级目录；确需新分类，先更新本文件和 `index.html` 的 `CATS` 数组再迁文件
- 清理 macOS 解压产生的 `._*` 垃圾文件，不要提交到站点

## 4. 部署 SOP（有 ECS 执行权限的 Agent）

```bash
# Step 1 备份（红线，永远先做）
tar czf /var/www/backups/new-file-$(date +%Y%m%d%H%M%S).tgz -C /tmp 新文件.html

# Step 2 上传（二选一）
#  a) 云助手直传（小文件，<32KB）：
aliyun ecs RunCommand --RegionId cn-wulanchabu --InstanceId.1 i-0jlh6m34jcpye7fyy6d9 \
  --Type RunShellScript --CommandContent 'echo "<base64>" | base64 -d > /var/www/desktop-html/投资/文件.html'
#  b) OSS 中转（大文件/中文文件名推荐）：
#     agent 本地: aliyun oss cp 文件.html oss://agent-kanban/tmp/ --region cn-wulanchabu
#             aliyun oss sign oss://agent-kanban/tmp/文件.html --timeout 600 --region cn-wulanchabu
#     ECS 执行:   curl -sS -o /var/www/desktop-html/投资/文件.html '<预签名URL>'
#     ⚠️ 管道会吞掉 oss cp 的失败退出码，上传后必须 oss stat 核对字节数

# Step 3 放入分类目录（见第 2 节），确认同名侧车同迁
# Step 4 验证
curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:8011/投资/文件.html'   # 期望 200
curl -s 'http://127.0.0.1:8011/listing/投资/' | python3 -c 'import json,sys;print(len(json.load(sys.stdin)))'  # 计数 +1
# Step 5 归档 + 清理
aliyun oss cp 文件.html oss://agent-kanban/backup/desktop-html/ --region cn-wulanchabu
aliyun oss rm oss://agent-kanban/tmp/文件.html --region cn-wulanchabu   # 中转残留必清
```

**回滚**：文件级从备份 tar 恢复即可；若动过 nginx 配置，`cp 备份.conf` 后 `nginx -t && systemctl reload nginx`（本站常规加文章**不需要**动 nginx）。

## 5. 进阶：精装卡片（补 META）

自动收录的卡片标题准确但无简介。如需精装卡片（标题+简介+标签）：

**主路径（v1.1 起推荐）：本地 build.py 重建**
1. 在 `build.py` 的 `NEW_META` 中加条目——**key 是裸文件名**（如 `"我的新文章.html": (标题, 简介, 标签)`）
2. **同名文件必须注册进 `CAT_FILES` 对应分类列表**，否则不出卡（见 §8）
3. `python3 build.py` → 应看到 `meta=N` 数量增加 → index.html + 分类清单.csv 走 OSS 中转回传 ECS

**旧路径（手动改 ECS 上的 index.html，仅急用时）：**

1. 备份：`cp -a index.html index.html.bak-meta-$(date +%Y%m%d%H%M%S)`
2. 在 `index.html` 的 `const META = {` 中插入（key 必须是 `目录/文件名`）：

```js
"投资/我的新文章.html": {
  "title": "中文标题（≤30字）",
  "desc": "基于实际内容的一句话简介（≤120字），写给三个月后的自己",
  "tag": "投资 · 子主题 · 形态"
},
```

3. 本地改完走 OSS 中转回传 ECS（同 Step 2b），`ls -la` 核对字节，浏览器强刷验证
4. 全站现有 META 的分类清单见 [/工具/分类清单.csv](/工具/分类清单.csv)（与站点同步维护）

## 6. 红线（违反即事故）

- ❌ 不动 nginx 其他 server 块、`/quota` 反代、`fq-book/`、`share.js`、`track.js`
- ❌ 不删任何 `*.bak-*` 备份文件
- ❌ 不把 AK/密钥写入站点可访问文件
- ❌ >50MB 文件先 `df -h` 确认磁盘再传
- ❌ 不在生产目录试跑未验证的脚本

## 7. 发布前自检清单

- [ ] 文章 HTTP 200（新路径）
- [ ] `/listing/<分类>/` 计数 +1
- [ ] 首页卡片出现、标题为中文（自动提取或 META）
- [ ] 同名侧车资源 200（若有）
- [ ] 随机抽 3 条旧扁平直链仍 200
- [ ] 备份已落盘、OSS 中转已清理

---

## 8. 构建器规则（index.html 的隐形约束，2026-10-19 实证）

站点首页由本地 `build.py`（`/home/z/my-project/desktop-html-new/`）生成，两条隐形规则：

- **`NEW_META` 的 key 是裸文件名**（`"russia_plague_qa.html"`），最终渲染出的 `const META` 才带「目录/文件名」前缀——写错格式会静默走兜底（tag=分类名、desc=标题）
- **文件必须注册进 `CAT_FILES` 分类列表**才会进 META/CSV，否则只被首页运行时自动收录（无简介）
- 重建后核对 `articles=N meta=N` 两数相等；`分类清单.csv` 由 build.py 同步生成，改完 META 必须重传 CSV

## 9. 全站审计经验（2026-10-19 首次全站体检沉淀）

写审计/修复脚本时已知误报源，先排除再动手：

- **侧车引用检查不要 `lstrip("./")`**：会把绝对路径 `/share.js` 剥成 `share.js` 而误报缺失
- **URL 编码的 href 是可达的**：`href="A%E8%82%A1....html"` 浏览器解码后命中中文文件名，别当断链修
- **JS 模板字面量**（`${r.url}`）会被当成相对链接，需排除
- **AK 红线扫描**：`LTAI` 四字母可能恰好出现在 base64 数据内部（美国地图页实证），命中后必须看上下文确认是否为 `LTAI+12位` 的离散 token
- **CSS 属性选择器匹配 href 时**，encoded 中文匹配不到（浏览器解析行为），卡片存在性验证用 `.card` 文本过滤
- 修复一律先 `cp file file.bak-opt-时间戳`，审计发现的每个「断链」先 curl 实证再修
