# ADR-002 · B 档实施: anchors/<slug>/ 子目录引入 · 知识库与流水线物理解耦

| 字段 | 值 |
|---|---|
| **状态** | `accepted` · 2026-05-28 单 atomic commit 落地 |
| **日期** | 2026-05-28 |
| **决策者** | CTO + 项目主理 |
| **超越** | 承接 [ADR-001 §2.2](ADR-001-multi-anchor-architecture.md#22-b-档-per-anchor-profile-中期) B 档定义 |
| **相关** | [`anchors/tian/README.md`](../../anchors/tian/README.md) · `config.yaml` · `panels/default.yaml` · `.gitignore` |

---

## 1. Context

ADR-001 提出 A → B → C 三档演进。A 档 (符号性配置) 在前一个 PR 已落地: `config.yaml` 加 `anchor:` 段, `panels/default.yaml` 加 `anchor_slug` 字段。但路径仍 hardcode (`skills/tian-perspective/`, `raw/tian-interviews/`, `raw/feishu-laotian/`), per-anchor 数据没有物理隔离。

用户明确诉求 (2026-05-28): **"从飞书抓取、建wiki，抽象评委的动作，与使用 boss skills 的动作，两个动作应该解耦，这样可以拓展，建立任何一个老板的知识库"**。

这要求 B 档实施: 引入 `anchors/<slug>/` 子目录, 把 per-anchor 数据物理隔离, 让通用 skill 仓 (`skills/`) 与具体锚点数据完全解耦。

---

## 2. Decision

**单 atomic commit 实施 B 档**, 不分阶段。把 3 个明显 per-anchor 的目录迁到 `anchors/tian/`:

| 旧路径 | 新路径 | 性质 |
|---|---|---|
| `skills/tian-perspective/` | `anchors/tian/perspective/` | anchor 评委 doctrine, per-anchor |
| `raw/tian-interviews/` | `anchors/tian/raw/interviews/` | 锚点访谈, per-anchor |
| `raw/feishu-laotian/` | `anchors/tian/raw/feishu-laotian/` | 飞书过滤后锚点 raw 材料, per-anchor |

**保留不动** (这些是通用工具, 锚点无关, 路径含 `tian` 是历史命名):

| 保留路径 | 不动原因 |
|---|---|
| `skills/tian/` | /boss 用户面 entry, 通过 config 查 anchor, 通用 |
| `skills/tian-judgement-orchestrator/` | Phase 0-5 流水线实现, 通用 (orchestrator 一个) |
| `skills/laotian-adapter/` | 飞书抓取工具适配器, 工具通用 (laotian 工具本身) |
| `skills/{industry-trend,strategic-vision,customer-strategy,product-strategy,org-strategy,financial-strategy}-perspective/` | 6 个维度评委 doctrine, 锚点无关 |
| `_wiki/` | Wiki 编译产物, 当前单 Wiki, per-anchor 拆分推迟到 v4 |
| `raw/{clippings,flomo,market-reports,archive,todo}/` | 通用来源 (与锚点无关) |

---

## 3. 实施详细

### 3.1 · 文件移动 (3 个 `mv`)

```bash
mkdir -p anchors/tian/raw
mv skills/tian-perspective    anchors/tian/perspective
mv raw/tian-interviews        anchors/tian/raw/interviews
mv raw/feishu-laotian         anchors/tian/raw/feishu-laotian
```

git 识别为 rename, 历史保留。10 个 tracked 文件迁移 (8 perspective + 2 README), 322 个 gitignored 文件物理跟随 (不入 git)。

### 3.2 · `.gitignore` 同步 (★ 关键防护)

旧路径条目保留 (defense-in-depth, 旧路径误重建仍 deny), 新增 B 档段:

```gitignore
# ─── anchors/<slug>/raw/ · B 档 per-anchor 数据隔离 ──
anchors/*/raw/interviews/*
!anchors/*/raw/interviews/README.md
anchors/*/raw/feishu-laotian/*
!anchors/*/raw/feishu-laotian/README.md
anchors/*/raw/feishu-laotian/.quarantine/
anchors/*/raw/feishu-laotian/.review/
anchors/*/raw/feishu-laotian/_meta/

# anchors/<slug>/_wiki/ — 该锚点的 Wiki 编译产物 (推迟到 v4)
anchors/*/_wiki/*
!anchors/*/_wiki/README.md
```

**事故记录**: 第一次 `git add anchors/` 没先更新 .gitignore, 332 文件 (含 156k confidential 行) 被 staged。立即 `git reset HEAD`, 修 .gitignore, 再 `git add`。完整 timeline 见本 PR commit log。

### 3.3 · 引用更新 (~50 文件)

用 perl batch replace, 排除 `.gitignore` (defense 旧条目保留):

```bash
perl -pi -e '
  s|skills/tian-perspective|anchors/tian/perspective|g;
  s|raw/tian-interviews|anchors/tian/raw/interviews|g;
  s|raw/feishu-laotian|anchors/tian/raw/feishu-laotian|g;
'
```

覆盖: `config.yaml` `panels/default.yaml` `CLAUDE.md` `README.md` `Makefile` `scripts/*.{py,sh}` `docs/*` `tests/*` `skills/tian/SKILL.md` `skills/tian-judgement-orchestrator/SKILL.md` `skills/laotian-adapter/SKILL.md`

### 3.4 · `anchors/tian/README.md` 建立

说明 sub-vault 边界 + 加新锚点的步骤 + 未来扩展位 (`_wiki/`, `panel.yaml`)。

### 3.5 · 配置链路验证

```yaml
# config.yaml
anchor:
  slug: tian
  perspective_skill: anchors/tian/perspective    # 已改 (从 skills/tian-perspective)
  raw_dirs:
    - anchors/tian/raw/interviews                # 已改
    - anchors/tian/raw/feishu-laotian            # 已改
```

```yaml
# panels/default.yaml
anchor_slug: tian                                # A 档已加
judges:
  - slug: tian
    skill_path: anchors/tian/perspective/SKILL.md  # 已改
```

---

## 4. Consequences

### 4.1 · 收益

- **物理解耦**: per-anchor 数据 (`anchors/tian/`) 与通用工具 (`skills/`) 完全分离, 任何老板新建知识库的成本降到 "mkdir + 写 perspective SKILL.md + cp panel"
- **可隔离**: 多锚点情境下, 每个老板的数据天然隔离, 不会互相污染
- **配置驱动**: 用户面 entry skill 通过 `config.yaml` 找 anchor, panel 通过 `anchor_slug` 找 anchor, 全部走集中配置
- **演进路径**: 为 v4 的 `anchors/<slug>/_wiki/` per-anchor Wiki 拆分 + C 档的两 repo 分离铺好路

### 4.2 · 接受的 tech debt

- **`skills/tian/` 仍叫 tian**: 命令 entry skill 的目录名保留 (改名要重跑 install_tian_skill.sh + 更新所有 docs 引用, 收益不抵成本)
- **`skills/tian-judgement-orchestrator/` 仍叫 tian-***: 同上
- **`skills/laotian-adapter/` 名字含 laotian**: 工具是通用的 (lark-cli wrapper), 但名字凝固了具体抓取工具 — 不改, 因为这是工具的真实名字
- **`_wiki/` 未 per-anchor 拆分**: 当前单一 Wiki 仍 ingest 所有锚点的 raw, 不区分。多锚点情境下应该拆 `anchors/<slug>/_wiki/`, 但当前只有 1 个锚点, 不必。v4 启动 (当 ≥ 2 锚点活跃)。
- **`config.yaml` 只 hold 一个 anchor**: 当前单锚点, `anchor:` 段是 singular。多锚点时改为 `anchors:` list + 默认锚点字段。

### 4.3 · 路径冲突风险

`config.yaml` `ignore:` 段已更新, 但 `raw/feishu-laotian/` 旧路径仍在 `.gitignore`。如果未来误把数据 commit 到旧路径, `.gitignore` 仍 deny → 安全。**两套 ignore 共存 (旧 + 新)**, defense-in-depth。

---

## 5. Alternatives Considered

| 方案 | 为什么没选 |
|---|---|
| **不动文件结构, 只加 symlinks** (`anchors/tian/perspective → skills/tian-perspective`) | 引入 symlink 间接, 工具脚本不一定跟符号链接走; git 对 symlink 行为各 OS 不一 |
| **同时 rename `skills/tian-*` 通用 skill** | 5 个文件 + install_tian_skill.sh + ~30 doc 引用 + symlink 重建, 大量收益微薄的命名工作; 留作 C 档清理 |
| **拆 `_wiki/` 到 `anchors/tian/_wiki/`** | 单锚点时无意义, 反而破坏 sage-wiki 现成配置; 推迟到多锚点出现时 |
| **分多 commit 实施** (mv 单独 commit, 引用更新单独 commit, ADR 单独 commit) | mv 后中间状态 broken (引用旧路径但文件已迁), 不应有 broken commit on main; 强制 atomic |
| **保留旧路径 + 新路径双写过渡期** | 双源数据不一致风险 + sage-wiki ingest 两次; 不值 |

---

## 6. Migration Plan: 何时启动 v4 / C 档

**v4 触发** (per-anchor `_wiki/` 拆分):
- ≥ 2 个锚点活跃使用 `anchors/<slug>/`
- 当前单 `_wiki/` 无法区分哪个锚点贡献了 entities

**C 档触发** (两 repo 分离 `boss-skills` + `boss-vault-<slug>`):
- B 档稳定 ≥ 1 季度
- 外部用户对 boss-skills 表达兴趣
- 多锚点的 confidentiality 隔离需求出现 (不同老板的数据不能共 vault)

---

## 7. Verify (本 PR 必过 checks)

- [x] `git status` 显示 0 confidential 数据 staged (332 文件误 staged 已 reset 修复)
- [x] `.gitignore` 同时含旧 + 新路径 deny (defense)
- [x] `config.yaml` yaml syntax valid + `anchor.perspective_skill` 指向 `anchors/tian/perspective`
- [x] `panels/default.yaml` `anchor_slug` + `skill_path` 一致
- [x] `anchors/tian/perspective/SKILL.md` 存在 + 8 个 references 文件齐
- [x] `redact_check.py` 在 3 个对外网站上 PASS (本次未动对外网站, 沿用前次 PASS)
- [x] 没有任何文件含 broken old path (`skills/tian-perspective/`, `raw/tian-interviews/`, `raw/feishu-laotian/` 全部替换为 `anchors/tian/`)
- [x] `anchors/tian/README.md` 说明 sub-vault 边界
- [x] 本 ADR 记录实施细节 + tech debt

---

*ADR-002 · accepted · 2026-05-28 · 见 [ADR-001](ADR-001-multi-anchor-architecture.md) · [`anchors/tian/README.md`](../../anchors/tian/README.md)*
