# Wayfinder

> 规划一大块工作——超过一次 agent 会话能容纳的体量——在你的 Issue 跟踪器上以共享的决策 ticket 地图形式呈现，逐个解决，直到通往目的地的道路变得清晰。

- Skill: `devcxl/wayfinder` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add devcxl/wayfinder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/devcxl/wayfinder/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: devcxl (https://skillmd.com/u/devcxl)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/devcxl/wayfinder

---


一个模糊的想法来了——大到一个 agent 会话装不下，而且笼罩在迷雾之中：从当前位置到**目的地**的路线还不 visible。Wayfinding 就是寻找那条路线，而不是冲向目的地。本技能将其绘制为 Issue 跟踪器上的**共享地图**，然后逐个处理其**决策 ticket**——问题本身，其答案是一个决策，而非构建中的可交付物切片——直到路线清晰。

每个项目的目标各不相同，命名目标是绘图的第一个行为——它塑造了每一个 ticket。它可能是一份要交付并迭代的规格说明、一个在规划开始前要锁定的决策、或者一个原地进行的变更（如数据结构迁移）。地图是领域无关的——工程工作、课程内容，无论什么形态都适用。

## 规划，而非动手

Wayfinder 默认是**规划**工具：每个 ticket 解决一个决策，地图在路线清晰时完成——不再有任何需要决定的事情，就可以交给别人去动手了。想要直接动手做的冲动，通常是你已经抵达地图边缘的信号，是时候交接了。项目可以在其**笔记**中覆盖这一设定——将执行任务也纳入地图——但默认情况下，产出的是决策，而非可交付物。

## 用名称来引用

每个地图和 ticket 都是一个 issue，因此它有一个**名称**——它的标题。在人读取的一切内容中——叙述、地图的"已有决策"部分——都通过名称来引用，绝不使用原始 ID、编号或短横线标识。一堵 `#42, #43, #44` 组成的墙难以阅读；名称则一目了然。ID 和 URL 不会消失——但名称包裹着链接——它们只是活在名称*内部*，而不是替代它。

## 地图

地图是此仓库 Issue 跟踪器上的一个 issue，带有 `wayfinder:map` 标签——这是权威产出物。它的 ticket 是地图的子 issue。

地图是一个**索引**，而不是仓库。它列出已做出的决策并指向包含其细节的 ticket；一个决策只存在于一个地方——它的 ticket 中——因此地图从不重述它，只摘要它并链接。

**地图、其子 ticket、阻塞关系和前沿查询在物理上位于何处，取决于具体的跟踪器。** Issue 跟踪器应已提供给你——如果没有，请告诉用户运行 `/setup-matt-pocock-skills`。查阅跟踪器文档的"Wayfinding 操作"一节了解此仓库如何表达它们。如果未提供跟踪器，默认使用本地 Markdown 跟踪器。

### 地图正文

整个地图以低分辨率加载，每个会话一次。打开的 ticket **不**在此列出——它们是打开的子 issue，通过查询找到。

```markdown
## 目的地

<到达此地图终点时的样子——该目标最终产出的规格、决策或变更。一两行；每个会话在选择 ticket 前都会以此为导向。>

## 笔记

<领域；每个会话应查阅的技能；此工作的固定偏好>

## 已有决策

<!-- 索引——每个已关闭 ticket 一行：足以判断相关性，然后点击链接获取 ticket 中的详细内容 -->

- [<已关闭 ticket 标题>](link) — <一行答案摘要>

## 尚未明确

<!-- 见"战争迷雾"：范围内的迷雾，尚不能创建 ticket；随着前沿推进而毕业-->

## 范围外

<!-- 见"范围外"：目的地之外排除的工作；已关闭，永不毕业-->
```

### Ticket

每个 ticket 都是地图的**子 issue**；跟踪器的 issue ID 是其标识。其正文是问题，大小限制在一次 100K token 的 agent 会话：

```markdown
## 问题

<该 ticket 解决的决策或调查>
```

每个 ticket 带有 `wayfinder:<type>` 标签——`research`、`prototype`、`grilling`、`task` 之一（见 [Ticket 类型](#ticket-类型)）。

一个会话通过将 ticket **分配**给推动地图的开发人员来**认领**它，**先**做这个，在开始任何工作之前，这样并发会话会跳过它。那个分配人*就是*认领：一个打开的、未分配的 ticket 就是未被认领的。

阻塞关系使用跟踪器的**原生**依赖关系——这很关键，因为它能让前沿*在视觉上*呈现在跟踪器自己的 UI 中，让人可以在不打开地图的情况下看到哪些是可领取的。只有当一个跟踪器缺少原生阻塞功能时才回退到正文约定。一个 ticket 在**所有**阻塞它的 ticket 都关闭时即为**已解除阻塞**；**前沿**就是打开的、未阻塞的、未分配的子 ticket——已知领域的边界。

答案不是正文的一部分——它是在解决时记录的（见[推进地图](#推进地图)）。在解决 ticket 过程中创建的资产通过链接关联到 issue，而不是粘贴进去。

## Ticket 类型

每个 ticket 要么是 **HITL**（人在回路——与能自主发言的人*协作*推进），要么是 **AFK**（由 agent 独立驱动）。HITL ticket 只能通过实时交流解决；agent 不能替代人类的那一侧（自己回答自己问题的 grilling agent 就破坏了这一点）。

- **Research** (AFK)：阅读文档、第三方 API 或本地资源如知识库来揭示一个决策所依赖的事实。由调用 Skill 工具并传入 "research" 的子代理解决。当需要当前工作目录之外的知识时使用。
- **Prototype** (HITL)：通过制作一个廉价、粗略、具体的人工产物来提高讨论的逼真度——大纲、初期草稿、桩代码、或通过调用 Skill 工具并传入 "prototype" 实现的 UI/逻辑代码。将原型作为资产链接。当"它应该是什么样子"或"它应该表现为什么行为"是关键问题时使用。
- **Grilling** (HITL)：对话。默认情况。始终调用 Skill 工具两次，分别传入 "grilling" 和 "domain-modeling"。
- **Task** (HITL 或 AFK)：在做出*决策*之前必须完成的纯手动工作——无需决策、原型或研究，但讨论被阻塞直到它完成。注册服务以便评判其 API、配置访问权限、迁移数据以便观察其形态。这是唯一一个*动手做*而非*做决策*的类型——它通过解除决策的阻塞来赢得自己的位置，而不是通过交付目的地。Agent 在可能时独立驱动（AFK）；否则交给用户一份精确的检查清单（HITL）。在工作完成时视为已解决；答案记录做了什么以及后续 ticket 依赖的任何衍生事实（凭据位置、新 URL、行数）。

## 战争迷雾

地图是*故意*不完整的：不要绘制你还看不到的东西。在活跃 ticket 之外就是**战争迷雾**——你能感觉到将要到来但还无法确定的决策和调查的依稀影像，因为它们取决于仍悬而未决的问题。解决一个 ticket 会清除它前方的迷雾，将现在可明确的内容毕业为新的 ticket——一次一个，直到通往目的地的道路清晰，不再有 ticket 留存。

地图的**尚未明确**部分就是写下那个依稀影像的地方：怀疑的问题、稍后要重新审视的区域、被暂缓的风险。它是通往目的地途中的未探索前沿——这里的一切都在范围内，只是还不够清晰到可以创建 ticket。尽情地写得粗略或完整，取决于可见度；它同时作为协作者的指示牌，指引工作的方向。

**迷雾还是 ticket？** 检验标准是你现在是否能精确陈述问题——*不是*你能否现在回答它。

- **Ticket 当**问题已经清晰——即使它被阻塞，你还不能对其采取行动。
- **尚未明确当**你还没法说得那么清楚。不要把迷雾预先切成 ticket 大小的块：它比 ticket 粗糙，迷雾中的一片区域可能会毕业成几个 ticket，也可能没有，取决于前沿何时到达它。

**尚未明确**排除已经决定的内容（那是"已有决策"）、已经是 ticket 的内容，以及范围外的内容（见下一节）。

## 范围外

迷雾只会在通往目的地的方向上聚集。目的地限定了范围，因此超出目的地的工作就是**范围外**——它不是迷雾，不属于**尚未明确**。它在地图上拥有自己的**范围外**章节：你有意识地从*本次*工作中排除的工件。是范围，而不是清晰度，决定了它放在这里。

范围外的工件永远不会毕业——前沿停在了目的地——因此只有目的地被重新划定后它们才可能回归，而且那时也是作为全新的项目，而非旧事重提。

将某物排除在范围之外是范围划定行为，而不是路线上的步伐。当一个已存在的 ticket 被发现处于目的地之外时——可能在绘图时错误地划入了范围，或者在一次解决结果中被暴露——**关闭它**（已关闭的 ticket 明确不在前沿上），并在**范围外**章节留下一行：摘要加上为什么在范围外，链接到已关闭的 ticket。它不会进入**已有决策**，后者记录的是实际走过的路线——范围边界不是路线上的一个步骤。

## 调用方式

两种模式。任一种情况下，**每个会话最多解决一个 ticket——研究 ticket 除外。**

### 绘制地图

用户用一个模糊的想法来调用。

1. **命名目的地。** 调用 Skill 工具两次，分别传入 "grilling" 和 "domain-modeling"，以确定此地图要寻找的目标——规格、决策或变更。目的地限定了范围，因此先确定它。
2. **绘制前沿。** 再次进行盘问，这次是**广度优先**：在整个空间展开而非深入任一分支，浮现开放的决策和现在可以迈出的第一步。**如果这次盘问没有浮现任何迷雾**——到达目的地的路线已经清晰，整个旅程小到一次会话就能装下——那你根本不需要地图。停下来，询问用户想怎么做。
3. **创建地图**（标签 `wayfinder:map`）：填写目的地和笔记，已有决策为空，将迷雾勾勒到**尚未明确**中。
4. **创建你现在可以明确的 ticket** 作为地图的子 issue——然后在**第二轮**中设置阻塞关系（issue 需要先有 ID 才能相互引用）。连线将它们归类为前沿和被阻塞；你还不能明确的一切留在迷雾中——即**尚未明确**章节。
5. **启动研究子代理。** 对于你刚创建的每个 `research` ticket，启动一个调用 Skill 工具并传入 "research" 的子代理来并行解决它，在一个可丢弃的 `research/<name>` 分支上捕获其发现，并在 ticket 中附上上下文指针。
6. 停止——绘制地图是一个会话的工作；它不会手动解决任何 ticket。

### 推进地图

用户用地图（URL 或编号）来调用。ticket 是**可选的**——没有指定时，你选取下一个决策，而不是用户。

1. 加载**地图**——低分辨率视图，不包括每个 ticket 正文。
2. 选择 ticket。如果用户指定了一个，使用它。否则按顺序取第一个前沿 ticket。**认领它**：在开始任何工作之前将其分配给自己。
3. 解决它——**按需放缩**：在需要时获取任何相关或已关闭 ticket 的完整正文；为 `## Notes` 块中指定的技能调用 Skill 工具。有疑问时，调用 Skill 工具两次，分别传入 "grilling" 和 "domain-modeling"。
4. 记录解决结果：将答案发表为**解决评论**，**关闭** issue，并在地图的"已有决策"中追加一个**上下文指针**。
5. 添加新浮现的 ticket（创建再连线）；升级因该答案而变得可明确的迷雾内容，从**尚未明确**中清除每个已升级的碎片，使其只存在于新 ticket 中。如果该答案揭示某个 ticket（当前或其他的）位于目的地之外，将其**排除在范围外**，而不是作为路线上的步骤解决。如果该决策使地图的其他部分失效，更新或删除那些 ticket。

用户可能并行运行未阻塞的 ticket，因此要预期其他会话可能同时在编辑跟踪器。

