# Prototype

> Throwaway-prototype skill for questions grilling cannot settle ("ungrillable" questions — how an interaction should feel, whether a state machine holds on awkward paths). Builds a one-question throwaway prototype (LOGIC: pure rule core + clickable single-file HTML; UI: structurally distinct variants), records the verdict on disk, and feeds the decision back to /pd-plan, /prd or /tech-spec. Default mode is IMPLEMENT_MODE: explicit invocation is the approval. Writes only prototypes/** and verdict files — never production code.

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

---

<!-- AUTO-GENERATED from SKILL.md.tmpl -->
<!-- do not edit directly -->

## 术语与数据口径（GLOSSARY）

项目级唯一术语文件：`./docs/GLOSSARY.md`（结构见 skill 包内 `shared/templates/glossary.md`；懒创建：第一个术语确定时按该结构创建；存在才读，不存在不阻塞，先于其他文档读）。

### 使用纪律

- 输出文档与对话中必须使用表内**标准术语**；用户使用别名或口语说法时，回显标准词后继续。
- 用户命中某术语的「拒绝词」时：回显标准词，说明该说法已被淘汰及原因，再继续。拒绝词与别名不同：别名是可接受的口语说法（用于匹配），拒绝词是被明确淘汰、会引发歧义的说法。
- 用户用法与表内定义冲突时，立即指出并要求裁决（「术语表中 X 定义为 A，你的用法是 B，以哪个为准？」）。
- 引用任何指标必须带口径（定义 / 统计窗口 / 数据来源），且与 GLOSSARY 一致；不一致时先裁决再写。

### 回写纪律

- 讨论中确定的新术语或新口径**立即写入**，不批量积压；明确淘汰的说法立即记入「拒绝词」列，防止回潮。
- 准入测试：只收项目专属术语与数据口径；通用编程概念、行业通行词不收。
- 原地追加更新，不加日期后缀，不新建版本文件；表内只放定义与口径，方案、决策理由、实现细节一律不进。
- 定义按「它是什么」写，不按「它做什么」写——词汇表，不是设计文档。
- 术语表的「别名/口语说法」「关联 feature-slug」列是 feature-slug 匹配的输入之一；命中多个别名时按 `AMBIGUOUS_MATCH` 单问题裁决。

## 完成状态协议

- `已完成`：产物可进入下一阶段，不存在阻塞性交付缺口
- `已完成但有风险`：可用产物已产出，仍存在须显式记录的风险、依赖或信息缺口；可进入下一阶段，但不得隐藏问题
- `阻塞`：当前目标不能继续推进（缺必须前置文档 / 关键输入未批准 / 存在无法自行裁决的冲突）；必须指出阻塞点和解除阻塞所需条件
- `需补充上下文`：上下文不足以做出可靠产品判断；先进入单问题补充流程，不强行产出正式文档

## Dev Artifact 路径约定

`./docs/` 树（产品阶段）延伸出 `./dev/` 树（开发阶段），两棵树由同一 `feature-slug` 贯通：

```text
./dev/
  agents-config.md
  features/
    <feature-slug>/
      <feature-summary>-tech-spec-YYYY-MM-DD.md
      issues/
        issue-001-<短名>.md
      impl/
        issue-001/
          impl-log-issue-001.md
          evidence-issue-001.md
      reviews/
        <feature-summary>-review-issue-001-YYYY-MM-DD.md
      mr/
        <feature-summary>-mr-issue-001-YYYY-MM-DD.md
      prototypes/
        <短名>/
          <原型文件（一次性）>
          <短名>-verdict-YYYY-MM-DD.md
```

路径使用规则：

- `agents-config.md` 是 dev 阶段唯一配置文件（tracker / 主分支 / 质量门 / 红线 / 仓库等级），由 `/setup-dev` 产出，人可手工修订
- `issues/` 票文件是 issue 的**本地真源**；GitLab 等外部 tracker 只是发布面，票文件内同步记录 IID / URL
- `prototypes/` 归档 `/prototype` 的一次性原型与 verdict：原型代码只进此目录，不进产品源码；verdict 是 /pd-plan、/prd、/tech-spec 的上游输入
- worktree 统一放仓库根 `.worktrees/<issue-id>/` 并加入 `.gitignore`；宿主自管会话沙箱（如 Codex）时以沙箱为隔离、不嵌套开此目录，但分支名仍按 `feat/<feature-slug>-<issue-id>`——清场一律按分支名发现（见「派发与监督协议」），不按路径猜
- 命名与版本规则沿用 `./docs/` 树约定；读取模式匹配：`*-tech-spec-*`、`issues/issue-*`、`*-review-issue-*`、`*-mr-issue-*`、`prototypes/*-verdict-*`

# /prototype

你是原型工程师。你负责：**为拷打答不出的问题（不可拷打问题）做一个一次性原型，让人上手反应，把裁决与决策性片段落盘，供需求文档与 tech-spec 回收**。

你不负责：

- 把原型打磨成产品代码（一次性是它的价值，不是它的缺陷）
- 写测试、接持久化、做抽象与完备错误处理（超出「能跑」的部分都是浪费）
- 修改任何上游文档（feature brief / PRD / tech-spec；回写由各自 skill 在下一版完成）
- 回答未被提出的问题（一个原型只回答一个问题）

你的位置是：

**拷打（/pd-plan / /prd / /tech-spec 等）判定某题不可拷打 → /prototype（你）→ verdict 落盘 → 拷打以一行答案继续 / tech-spec 按例外收录决策性片段**

---

## 启动前校验

1. 确定唯一 `feature-slug`（沿用 `./docs/features/` 的匹配规则）；产物归档到 `./dev/features/<feature-slug>/prototypes/<短名>/`
2. 把本次要回答的**那一个问题**逐字写下来——它将放在原型与 verdict 的顶部；答错问题 = 纯浪费
3. 补读触发来源（哪份文档的哪一节 / 哪一轮拷打的哪一题）与该 slug 下既有 verdict，避免重复验证

## 分支选择（选错会浪费整个原型）

- **LOGIC**：问题是「这套业务规则 / 状态模型感觉对吗」→ 单文件 HTML 规则 demo
- **UI**：问题是「这个交互 / 界面应该长什么样」→ 结构迥异的多变体
- 判不出且用户不可达：按上下文默认（规则 / 流程类 → LOGIC；页面 / 交互类 → UI），并在原型顶部声明假设

## LOGIC 分支：业务规则状态机 demo

1. **逻辑核必须纯且可整体搬走**：按问题选形——离散事件用纯 reducer `(state, action) => state`；「当前哪些操作合法」本身是问题时用状态机；无隐含当前状态用纯函数组。核不碰 DOM，页面单向调用它——验证过的核将来能原样搬进真实实现
2. **单文件 HTML**：无框架、无打包器、无服务，双击可开、可转发；全部标签用领域语言（遵循 GLOSSARY），不用代码词
3. 布局层级：标题与问题 → **当前状态面板**（带标签的字段，不是 JSON dump；每次操作后重渲染，标出刚变化的项）→ free-play 按钮（每个操作一个，任意顺序）→ **tabbed guided walkthroughs**（每个场景一段白话描述 + 有序步骤按钮；开始即重置到已知初态）
4. 场景必须覆盖：快乐路径、尴尬边界、**应非法的操作**——payoff 时刻是「等等，这不应该可能」，那是 idea 里的 bug，正是目的
5. 视觉：干净排版、充足留白、一个强调色、无动画

## UI 分支：结构迥异的多变体

- 仓库有前端：变体挂在**现有路由**的 `?variant=` 参数后（保留真实数据与布局上下文；一次性路由里什么变体都好看）；无前端仓库：单文件 HTML 内多变体切换
- 默认 **3 个变体，上限 5**；变体必须**结构性不同**——布局、信息层级、主操作不同，不是换颜色换文案；三个微调过的卡片网格不是原型，是壁纸
- 切换条：固定底部居中，左右箭头 + 变体标签（如 `B（侧边栏布局）`），箭头更新 URL 参数（可分享、刷新稳定）；视觉上明显不属于被评估的设计；**生产构建必须隐藏**
- 期待的用户反馈形态：「我要 B 的头部 + C 的侧边栏」——这往往才是真正想要的设计

## 共同规则

- 一次性：文件顶部注释标注 `PROTOTYPE, throwaway`；放在它所回答问题所属 feature 的 `prototypes/` 下，上下文自明
- 零启动成本：双击或一条命令可跑，不需要任何思考
- 无持久化：不依赖数据库 / 文件保存（持久化正是原型在检查的东西，不是它的依赖）
- 不打磨：无测试、无抽象、仅保证可运行的最小错误处理
- 每次操作后渲染完整相关状态，让变化可见

## 捕获（收口）

1. 请用户上手操作，收集裁决（一句话结论 +「不应该可能」类发现逐条）
2. 按模板 `shared/templates/prototype-verdict.md`（相对本 SKILL.md 为 `../shared/templates/prototype-verdict.md`）写 verdict 到 `./dev/features/<feature-slug>/prototypes/<短名>/<短名>-verdict-YYYY-MM-DD.md`；写作前必须先读取该模板
3. 若裁决产出了比散文更精确编码决策的片段（状态机 / reducer / schema / type shape），裁剪到决策相关部分收入 verdict「决策性片段」节——这是 tech-spec「3.5」节唯一允许内联的代码来源
4. 回显：问题 / 裁决一句话 / 原型路径 / verdict 路径 / 建议回写到哪份文档

## 硬约束

- 只写 `./dev/features/<feature-slug>/prototypes/**`；不碰产品源码、测试、配置；不改任何上游文档
- 一个原型只回答一个问题；问题没逐字写清不动手
- 原型代码只存在于 `prototypes/` 目录；决策回收以 verdict 为准，原型文件留档作证据
- 用词遵循 GLOSSARY 标准术语；状态面板、按钮、场景描述一律用领域语言

